satijalab / seurat

R toolkit for single cell genomics
http://www.satijalab.org/seurat
Other
2.18k stars 891 forks source link

Fix naming of layers of CreateAssay5Object() function and allow assay and layer names to be modified after creation #7432

Open ScreachingFire opened 1 year ago

ScreachingFire commented 1 year ago

Hello!

I came across a problem where I could not change the names of assays and layers after the creation of a Seurat Object. For example:

Assays(scdata) <- c("ASSAY1","ASSAY2")
Layers(scdata[["RNA"]]) <- c("LAYER1", "LAYER2")

These return the following errors:

Error in Assays(scdata) <- c("RNA1", "SCT1") : 
  could not find function "Assays<-"

Error in Layers(scdata[["RNA"]]) <- c("counts", "scale.data") : 
  could not find function "Layers<-"

I realize that if a default assay has its name modified then DefaultAssay() would also have to have its name changed, but layers would not have this issue at least so it might be worth it to focus on layers hopefully. I am trying to read in an assay stored as a named list and unfortunately the CreateAssay5Object() function prepends the string "counts." to each layer name, which I am trying to avoid. Would it be possible to allow assay or at least layer names to be modified after their creation and fix CreateAssay5Object() so that if a named list of multiple data matrices is supplied, the layer names do not have "counts." added before the name. E.g:

> CreateAssay5Object(named_list_of_data) # named_list_of_data was created with list(counts = datamat1, scale.data = datamat2)
 Assay (v5) data with 21703 features for 22058 cells
 First 10 features:
 RP11-34P13.7, FO538757.2, AP006222.2, RP4-669L17.10, RP11-206L10.9, FAM87B, LINC00115, FAM41C, RP11-54O7.1, SAMD11 
 Layers:
 counts.counts, counts.scale.data # These should be counts, scale.data
ScreachingFire commented 1 year ago

Okay I found a work around by doing:

names(scdata@assays[["assay_name"]]@layers) <- c("name1", "name2")

Nevermind it generates the error:

scdata[["assay_name"]]
Assay (v5) data with 21703 features for 22058 cells
Error in match.arg(arg = i, choices = colnames(x = x)) : 
'arg' should be one of “counts.counts”, “counts.scale.data”

But still something to keep in mind hopefully as changing names with Layers(scdata)<- seems more intuitive

mihem commented 1 year ago

Not part of the Seurat team, but also interested in that.

I think this is related to/a duplicate of https://github.com/satijalab/seurat/issues/7316.

So, not possible to rename layers yet, except this workaround with join and split.

ScreachingFire commented 1 year ago

I ended up creating a function to create an assay with the correct names in the meantime

create_assayv5 <- function(assay_data) {

  a5obj <- SeuratObject::CreateAssay5Object(counts = assay_data[[1]]) # Create temporary assay with initial layer

  if (names(assay_data)[1] != "counts") {
    init_layer <- names(assay_data)[1]

    a5obj[[init_layer]] <- assay_data[[1]] # Add data with correct layer name
    DefaultLayer(a5obj) <- init_layer

    a5obj$counts <- NULL # Remove old layer
  }

  assay_data[[1]] <- NULL; gc() # Free up space

  if (length(assay_data) != 0) { # If there are other layers, add them
    for (layer in names(assay_data)) {
      a5obj[[layer]] <- assay_data[[layer]]
    }
  }

  return(a5obj)
}
jreimertz commented 1 month ago

Wanted to comment on this as this issue is still open, but I was able to use:

names(scdata@assays$assay_name@layers) <- c("name1", "name2")

and it looks like @ScreachingFire 's solution also works now

names(scdata@assays[["assay_name"]]@layers) <- c("name1", "name2")