I have a R script that subsets out the tumor cells from 6 different individual seurat objects.

It gets a list of file paths for all RDS files containing the expression data for multiple datasets in a directory. It creates two empty lists, datasets and dataset_index, to hold the subsets of tumor cells from each dataset and their corresponding indices, respectively. It loops through each file path, reads the RDS file, and subsets the tumor cells from the expression data. If the dataset does not contain any tumor cells, it prints a message indicating that fact. The subsets of tumor cells are appended to the datasets list and their corresponding indices are appended to the dataset_index list.

scfiles = list.files('/LungDataSets/',pattern = '.*SCTransform_Symphony.*.RDS',recursive=TRUE)

scfiles = paste('/LungDataSets/',scfiles,sep='')

datasets = list()
dataset_index = list()

for (i in 1:length(scfiles)) {
    scData = readRDS(scfiles[i])
    if (is.element('Tumor', unique(scData$cell_ann)))  {
        tumorData = subset(scData,subset = cell_ann=='Tumor')
        datasets = append(datasets,tumorData)
        dataset_index = append(dataset_index,toString(i))
    else {
        print(c(scfiles[i], 'does not contain Tumor cells'))

Now I want to merge all those tumor cells from the 6 datasets into one seurat object.

I've tried merge and rbind but they don't work.

megaObject <- merge(datasets)
Error in as.data.frame.default(x[[i]], optional = TRUE) : 
  cannot coerce class ‘structure("Seurat", package = "SeuratObject")’ to a data.frame

3 Answers 3


The first parameter of merge should be a Seurat object, the second (y) can be one Seurat object or a list of several. Try:

merge(x = datasets[[1]], y = datasets[-1])

See the merge vignette for more details. You may want to use the add.cell.ids option to be able to tell which dataset each cell originated from.


You should be able to use something like this:

    f = function(x, y) {merge(x, y, merge.data = FALSE)},
    x = datasets # list of Seurat objects

This will create a new Seurat object based on the multiple seurat objects in your list. It might be good idea to store the "sample" information within the metadata slots of individual objects. Probably a better approach is to have cell barcodes of each sample prefixed with the sample id.


I can't reproduce things quickly without a minimum reproducible example (e.g. with sample data from the package). However, the error is telling you that R cannot convert the object to a dataframe when trying to use merge() (at least I suspect that this error occurred when you ran merge() since you posted it right under it). I suggest you convert everything you need to a dataframe (there are quite some questions, e.g., on biostars regarding this conversion). Everything you need because a SeuratObject cannot simply be cast to a dataframe, only parts of it, e.g., data_transcripts_seurat@assays$SCT@counts %>% as.matrix() %>% t() %>% as.data.frame() (from this biostars question). However, you might need some other information. Therefore, I suggest you explore the SeuratObject using RStudio and check what information you want to draw from it. After the (interesting) parts of the SeuratObject have been cast to dataframes, e.g., in the for-loop, you can go ahead with merging.

  • 2
    $\begingroup$ There is no need to convert the Seurat object into a data frame, because a merge() function exists for Seurat objects. $\endgroup$
    – Cloudberry
    Commented Apr 24, 2023 at 18:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.