satijalab / seurat-object

https://satijalab.github.io/seurat-object/
Other
23 stars 26 forks source link

Adding feature metadata to Seurat v5 Object using SeuratObject::AddMetaData does not work #125

Open grantn5 opened 1 year ago

grantn5 commented 1 year ago

When trying to add feature metadata to Seurat v5 object using the nromal SeuratObject::AddMetaData() you get the following error

Error in `LayerData<-`:
! 'layer' must be a single non-empty string

Reprex

library(Seurat)
library(SeuratData)
library(BPCells)
library(dplyr)
options(Seurat.object.assay.version = "v5")

pbmc3k <- SeuratData::LoadData("pbmc3k")

pbmc3k_feature_data <- pbmc3k[["RNA"]][["counts"]] |>
  dplyr::mutate(new_vairable =sample(1:100, nrow(pbmc3k), replace = TRUE))

pbmc3k[["RNA"]] <- SeuratObject::AddMetaData(pbmc3k[["RNA"]], metadata = pbmc3k_feature_data)
samuel-marsh commented 5 months ago

Hi,

Not sure if this is still issue for you but figured I would post in case you or anyone else has same issue. There is slightly different procedure depending on whether you are adding to Assay or Assay5 object.

If adding to Assay then you can just provide vector of IDs:

suppressMessages(library(Seurat))
pbmc <- pbmc3k.SeuratData::pbmc3k
pbmc <- suppressMessages(UpdateSeuratObject(pbmc))
#> Warning: Assay RNA changing from Assay to Assay

random_ids <- paste0("A", seq_len(length(Features(pbmc))))

pbmc[["RNA"]] <- AddMetaData(object = pbmc[["RNA"]], metadata = random_ids, col.name = "new_ids")

head(pbmc@assays$RNA@meta.features)
#>               new_ids
#> AL627309.1         A1
#> AP006222.2         A2
#> RP11-206L10.2      A3
#> RP11-206L10.9      A4
#> LINC00115          A5
#> NOC2L              A6

Created on 2024-04-25 with reprex v2.1.0

If you try with vector of IDs with Assay5 you get error:

suppressMessages(library(Seurat))
pbmc <- pbmc3k.SeuratData::pbmc3k
pbmc <- suppressMessages(UpdateSeuratObject(pbmc))
#> Warning: Assay RNA changing from Assay to Assay

pbmc_v5 <- CreateSeuratObject(counts = LayerData(pbmc))

random_ids <- paste0("A", seq_len(length(Features(pbmc_v5))))

pbmc_v5[["RNA"]] <- AddMetaData(object = pbmc_v5[["RNA"]], metadata = random_ids, col.name = "new_ids")
#> Error in `[[<-`:
#> ! No feature overlap between new meta data and assay

Created on 2024-04-25 with reprex v2.1.0

But if you use data.frame that contains matching ids to current assay features it works:

suppressMessages(library(Seurat))
pbmc <- pbmc3k.SeuratData::pbmc3k
pbmc <- suppressMessages(UpdateSeuratObject(pbmc))
#> Warning: Assay RNA changing from Assay to Assay

pbmc_v5 <- CreateSeuratObject(counts = LayerData(pbmc))

random_ids <- paste0("A", seq_len(length(Features(pbmc_v5))))
random_df <- data.frame(original = Features(pbmc_v5),
                        new_ids = random_ids)

pbmc_v5[["RNA"]] <- AddMetaData(object = pbmc_v5[["RNA"]], metadata = random_df, col.name = "new_ids")

head(pbmc_v5@assays$RNA@meta.data)
#>   new_ids
#> 1      A1
#> 2      A2
#> 3      A3
#> 4      A4
#> 5      A5
#> 6      A6

Created on 2024-04-25 with reprex v2.1.0

Best, Sam

nick-youngblut commented 4 months ago

@samuel-marsh do you know why pbmc_v5@assays$RNA@meta.data does not return a data.frame in which the row names are the feature names? It seems like one would want this crucial information in the meta.data data.frame object.

Numeric indices as rownames is not so useful:

pbmc_v5@assays$RNA@meta.data %>% rownames() %>% head()
# '1' '2' '3' '4' '5' '6'

...so one would need to do this "manually":

DF = pbmc_v5@assays$RNA@meta.data 
rownames(DF) = pbmc_v5@assays$RNA %>% rownames()