waldronlab / MultiAssayExperiment

Bioconductor package for management of multi-assay data
https://waldronlab.io/MultiAssayExperiment/
70 stars 32 forks source link

Assay levels are dropped in sampleMap after subsetByColData #317

Closed cvanderaa closed 2 years ago

cvanderaa commented 2 years ago

Hi Marcel, @LiNk-NY

I'm sorry to bother you again with a little bug in subsetByColData() (I really like this function of MAE), but it hinders some functionality in QFeatures.

Reproducible example

library(MultiAssayExperiment)
## Create 2 mock assays
m1 <- matrix(1:40, ncol = 4)
m2 <- matrix(1:16, ncol = 4) 
colnames(m1) <- paste0("A", 1:4) 
colnames(m2) <- paste0("B", 1:4) 
rownames(m1) <- letters[1:10]
rownames(m2) <- letters[1:4]
(se1 <- SummarizedExperiment(m1))
(se2 <- SummarizedExperiment(m2))
el <- ExperimentList(assay1 = se1, assay2 = se2)
(mae <- MultiAssayExperiment(el))
A MultiAssayExperiment object of 2 listed
 experiments with user-defined names and respective classes.
 Containing an ExperimentList class object of length 2:
 [1] assay1: SummarizedExperiment with 10 rows and 4 columns
 [2] assay2: SummarizedExperiment with 4 rows and 4 columns
Functionality:
 experiments() - obtain the ExperimentList instance
 colData() - the primary/phenotype DataFrame
 sampleMap() - the sample coordination DataFrame
 `$`, `[`, `[[` - extract colData columns, subset, or experiment
 *Format() - convert into a long or wide DataFrame
 assays() - convert ExperimentList to a SimpleList of matrices
 exportClass() - save data to flat files

Everything works nicely up to now, the levels in the sampleMap are as expected and constructing an MAE objects with the same attributes leads to the same object:

expect_identical(levels(sampleMap(mae)$assay), names(mae))
expect_identical(mae,
                 MultiAssayExperiment(experiments(mae), 
                                      colData(mae), 
                                      sampleMap(mae)))

I then add a selection variable that will remove all samples in one of the two assays, the issue doesn't occur in other cases.

mae$sel <- rep(c(TRUE, FALSE), each =4)
mae2 <- subsetByColData(mae, mae$sel)

The above test now breaks...

expect_identical(levels(sampleMap(mae2)$assay), names(mae2))
expect_identical(mae2,
                 MultiAssayExperiment(experiments(mae2), 
                                      colData(mae2), 
                                      sampleMap(mae2)))
Error: levels(sampleMap(mae2)$assay) not identical to names(mae2).
Lengths differ: 1 is not 2
Error: `mae2` not identical to MultiAssayExperiment(experiments(mae2), colData(mae2), sampleMap(mae2)).
Lengths: 2, 1
Names: Lengths (2, 1) differ (string compare on first 1)
Attributes: < Component “ExperimentList”: Lengths: 2, 1 >
Attributes: < Component “ExperimentList”: Names: Lengths (2, 1) differ (string compare on first 1) >
Attributes: < Component “ExperimentList”: Attributes: < Component “listData”: Length mismatch: comparison on first 1 components > >
LiNk-NY commented 2 years ago

Hi @cvanderaa Sorry for the delay. I will take a look today. Best regards, Marcel

LiNk-NY commented 2 years ago

Thanks Chris!