[Bioc-devel] Problem with S4 method dispatch: .. bug in methods package ? SummarizedExperiment, but not SingleCellExperiment
Axel Klenk
@xe|@k|enk @end|ng |rom gm@||@com
Thu Jan 23 15:31:18 CET 2025
Hi Martin and all,
> In principle it should be reproducible with only base R (incl
> methods package), not involving your given extra packages;
> just using functions setClassUnion(), ... etc from methods.
>
> Is that possible?
Yes, it is -- but I found that in order to reproduce the issue I need
to mimic the "original" constellation
where class A and its subclass C are defined in some example package
expkg and D, a subclass of C
is defined in a dependent package depkg. Then a method defined for a
class union U of class A and
some other class B will be found for an object of class C (same
package as A), but not one of class D
(different package)... I have prepared two packages expkg and depkg
on my GitHub to demonstrate
this as follows:
if(!requireNamespace("remotes", quietly = TRUE)) install.packages("remotes")
remotes::install_github(c("axelklenk/expkg", "axelklenk/depkg"))
library("expkg")
setClass("B")
setClassUnion("U", c("A", "B"))
setGeneric("Umethod", function(x) standardGeneric("Umethod"))
setMethod("Umethod", signature="U", function(x) cat("Found Umethod!\n"))
o <- new("C")
Umethod(o) ## it works!!
library("depkg")
p <- new("D")
Umethod(p)
## Error: unable to find an inherited method for function 'Umethod'
for signature 'x = "D"'
The packages contain nothing but the necessary setClass() and their
respective NAMESPACE
files are pretty simple. For expkg, the package defining superclasses A and C:
exportClasses(A)
exportClasses(C)
import(methods)
and for depkg, the package defining subclass D
exportClasses(D)
import(methods)
importClassesFrom(expkg,A)
importClassesFrom(expkg,C)
I have studied WRE 1.5[.6] and added "Depends: methods¨ to the
packages' DESCRIPTION files and
"import(methods)" to their NAMESPACE files but that didn't seem to
make a difference. Otherwise I didn't
find any hints in WRE.
Ah, and after running the code above, the inheritance relation between
U and C is "known" as well as
between A and D, but not between U and D:
> getClass("C")
Class "C" [package "expkg"]
No Slots, prototype of class "S4"
Extends:
Class "A", directly
Class "U", by class "A", distance 2
> getClass("D")
Class "D" [package "depkg"]
No Slots, prototype of class "S4"
Extends:
Class "C", directly
Class "A", by class "C", distance 2
> getClass("U")
Extended class definition ( "ClassUnionRepresentation" )
Virtual Class "U" [in ".GlobalEnv"]
No Slots, prototype of class "C"
Known Subclasses:
Class "A", directly
Class "B", directly
Class "C", by class "A", distance 2
Now, does that look like a bug in the methods package or rather like
'some "unhappy coincidence" in how the involved packages interact there'?
I have no idea how to tell -- and therefore will follow this advice:
> Otherwise, yes, do as you are advised, i.e. --> https://www.r-project.org/bugs.html
> and apply for an R bugzilla account.
Thanks to all for your help so far and any additional advice,
- axel
Am Mi., 15. Jan. 2025 um 09:08 Uhr schrieb Martin Maechler
<maechler using stat.math.ethz.ch>:
>
> >>>>> Axel Klenk
> >>>>> on Sat, 11 Jan 2025 01:16:49 +0100 writes:
>
> > Hi Hervé, Kasper, Helena and all,
> > and thanks a lot for your replies!
>
> > First of all, if this is a bug in the methods package, I'd of course
> > volunteer to report it -- sounds like a great learning opportunity
> > for the New Year. ;-)
>
> As an R corer with special interest in S4/ methods, I had wanted to chime in earlier:
> Yes, _if this is a bug in the methods package_
>
> In principle it should be reproducible with only base R (incl
> methods package), not involving your given extra packages;
> just using functions setClassUnion(), ... etc from methods.
>
> Is that possible?
>
> Of course, it might be that it is related to the use of
>
> ImportClassesFrom(),
> ImportMethodsFrom(),
> ExportClasses()
> ...
>
> directives in the involved packages' NAMESPACE files,
> and some "unhappy coincidence" in how the involved packages
> interact there ..
> but probably Hervé or you have already looked into these.
>
> Otherwise, yes, do as you are advised, i.e. --> https://www.r-project.org/bugs.html
> and apply for an R bugzilla account.
>
> Best,
> Martin
>
>
> > In my original message I tried to focus on the error and provided only
> > the code necessary to reproduce it but of course I'm happy
> > to provide more background and receive advice on design and maintainability.
>
> > The reason for class unions was the need to store any user-provided
> > data container in a slot of GSVA's parameter objects when
> > those were introduced. (Actually there is one for data
> > matrices/containers and another one for gene sets in lists or
> > GSEABase::GeneSetCollection.) As you seem to be a bit reluctant to
> > use class unions, is there a good way to avoid them as
> > the slot class in this case?
>
> > Once the class union existed, methods on the union were added to avoid
> > long functions with unwieldy if/else constructs, as the
> > number of supported containers is growing. However, so far there are
> > only two actual use cases for methods on class unions:
> > (1) the (containing) parameter object's show() method that includes
> > output from show() methods of the (contained) data objects,
> > with more specialized methods only required for matrix and dgCMatrix
> > that otherwise show() all of their content, and
> > (2) some method for extracting a matrix-like data object from a data
> > container -- assay() for SummarizedExperiment and derivatives,
> > exprs() for ExpressionSet, the object itself for matrix/dgCMatrix.
>
> > So, we are actually starting from the class unions rather than the
> > methods that could be replaced the way Hervé suggested.
> > The methods are just where the error message happened to appear and I
> > was not sure if this was caused by a bug or not expected
> > to work at all or a known issue requiring some special measures or ...
>
> > By the way, in the meantime we have been experimenting with the mock
> > example below -- which works as expected?!?
>
> > setClass("A") ## this would be like 'dgCMatrix'
> > setClass("B") ## this would be like 'SummarizedExperiment'
> > setClass("C", contains="B") ## this would be like 'SingleCellExperiment'
> > setClassUnion("U", c("A", "B"))
> > setGeneric("Umethod", function(x) standardGeneric("Umethod"))
> > setMethod("Umethod", signature="U", function(x) cat("Umethod!\n"))
> > o <- new("C")
> > Umethod(o) ## it works!!
>
> > Thanks in advance for your support and suggestions,
>
> > - axel
>
>
> > Am Fr., 10. Jan. 2025 um 18:17 Uhr schrieb Kasper Daniel Hansen
> > <kasperdanielhansen using gmail.com>:
> >>
> >> In my experience, class unions are hard to work with and quickly get out of hand. I don't really understand what you actually want to do, beyond defining a class union. My impression is that your main goal is to write simplified code. I could be wrong, but I doubt class unions is the best way to solve your problem. What you really need is that these classes share a common API in that you can do stuff like
> >> assay()
> >> on them. Either this common API already exists or it does not. It it already exists, there is - as far as I can tell - no gains from the class union. If it does not exist, you still need to write class specific code to get the API working.
> >>
> >> Like Herve, I suggest not starting with a method. I find that too many developers are too quick to reach for methods.
> >>
> >> We might be able to give you more useful feedback and help if you can tell us more precisely what you want to do.
> >>
> >> Best,
> >> Kasper
> >>
> >>
> >> On Thu, Jan 9, 2025 at 2:38 PM Hervé Pagès <hpages.on.github using gmail.com> wrote:
> >>>
> >>> Looks like a bug in the methods package to me.
> >>>
> >>> The extends() relationship looks transitive, as it should be:
> >>>
> >>> > extends("SingleCellExperiment", "SummarizedExperiment")
> >>> [1] TRUE
> >>> > is(new("SingleCellExperiment"), "ExpData")
> >>> [1] TRUE
> >>> > extends("SingleCellExperiment", "ExpData")
> >>> [1] TRUE
> >>>
> >>> Also is() is doing the right thing as Helena pointed out:
> >>>
> >>> > is(new("SingleCellExperiment"), "ExpData")
> >>> [1] TRUE
> >>>
> >>> However, when using the single-arg form of extends() to list all the
> >>> ancestor classes, ExpData is no longer seen as an ancestor of
> >>> SingleCellExperiment:
> >>>
> >>> > extends("SummarizedExperiment")
> >>> [1] "SummarizedExperiment" "RectangularData" "Vector"
> >>> [4] "ExpData" "Annotated" "vector_OR_Vector"
> >>>
> >>> > extends("SingleCellExperiment")
> >>> [1] "SingleCellExperiment" "RangedSummarizedExperiment"
> >>> [3] "SummarizedExperiment" "RectangularData"
> >>> [5] "Vector" "Annotated"
> >>> [7] "vector_OR_Vector"
> >>>
> >>> Same problem with selectSuperClasses(), which is an other way to list
> >>> all the ancestors of a given class:
> >>>
> >>> > selectSuperClasses("SummarizedExperiment", directOnly=FALSE)
> >>> [1] "RectangularData" "Vector" "ExpData" "Annotated"
> >>> [5] "vector_OR_Vector"
> >>>
> >>> > selectSuperClasses("SingleCellExperiment", directOnly=FALSE)
> >>> [1] "RangedSummarizedExperiment" "SummarizedExperiment"
> >>> [3] "RectangularData" "Vector"
> >>> [5] "Annotated" "vector_OR_Vector"
> >>>
> >>> And same problem when trying to retrieve this list directly from the
> >>> 'contains' slot of the class definitions:
> >>>
> >>> > names(getClass("SummarizedExperiment")@contains)
> >>> [1] "RectangularData" "Vector" "ExpData" "Annotated"
> >>> [5] "vector_OR_Vector"
> >>>
> >>> > names(getClass("RangedSummarizedExperiment")@contains)
> >>> [1] "SummarizedExperiment" "RectangularData" "Vector"
> >>> [4] "ExpData" "Annotated" "vector_OR_Vector"
> >>>
> >>> > names(getClass("SingleCellExperiment")@contains)
> >>> [1] "RangedSummarizedExperiment" "SummarizedExperiment"
> >>> [3] "RectangularData" "Vector"
> >>> [5] "Annotated" "vector_OR_Vector"
> >>>
> >>> Any volunteer to report this to the methods maintainer? (via the R bug
> >>> tracker)
> >>>
> >>> Anyways, not sure exactly what methods you're planning to implement for
> >>> ExpData derivatives. Have you considered doing something like this instead:
> >>>
> >>> .check_expdata <- function(expdata)
> >>> {
> >>> ok <- is.matrix(expdata) ||
> >>> is(expdata, "dgCMatrix") ||
> >>> is(expdata, "ExpressionSet") ||
> >>> is(expdata, "SummarizedExperiment")
> >>> if (!ok) stop("'expdata' must be a matrix or dgCMatrix or ",
> >>> "ExpressionSet or SummarizedExperiment derivative")
> >>> }
> >>>
> >>> foo <- function(expdata)
> >>> {
> >>> .check_expdata(expdata)
> >>> ...
> >>> ...
> >>> }
> >>>
> >>> Personally I find that using a union and method dispatch for this is a
> >>> little bit overkill.
> >>>
> >>> Best,
> >>>
> >>> H.
> >>>
> >>>
> >>> On 1/8/25 05:35, Helena L. Crowell wrote:
> >>> > Ui, my bad, messed up my environment… Indeed, I think what you had in mind doesn’t work. My guess is that the class union is “strict” in that method dispatch doesn’t just propagate to classes that inherit from what’s in the union.
> >>> >
> >>> > Anything against something like … which should definitely work (I think):
> >>> >
> >>> > setClassUnion("ExpData", c(
> >>> > "matrix", "dgCMatrix", "ExpressionSet",
> >>> > "SingleCellExperiment", "SummarizedExperiment”))
> >>> >
> >>> > What’s really weird imo is that is(se, "ExpData”) and is(sce, "ExpData”) both return TRUE, but still the SCE method can’t be found?
> >>> > Maybe someone else has more insights, sorry!!
> >>> >
> >>> >> On Jan 8, 2025, at 14:11, Axel Klenk <axel.klenk using gmail.com> wrote:
> >>> >>
> >>> >> Hi Helena,
> >>> >>
> >>> >> thanks for your reply. Unfortunately it doesn't work for me -- when
> >>> >> copy+paste'ing your code
> >>> >> the error now occurs for SummarizedExperiment (transcript below,
> >>> >> including session info
> >>> >> that I had forgotten yesterday).
> >>> >>
> >>> >> In the current version of GSVA the class union contains all of SE, SCE
> >>> >> and SPE and we
> >>> >> still need to define all methods for all of them which doesn't feel
> >>> >> right... but I must be doing
> >>> >> something wrong.
> >>> >>
> >>> >> Any ideas?
> >>> >>
> >>> >> Cheers,
> >>> >>
> >>> >> - axel
> >>> >>
> >>> >>
> >>> >>> library("Matrix")
> >>> >>> library("Biobase")
> >>> >> Loading required package: BiocGenerics
> >>> >>
> >>> >> Attaching package: 'BiocGenerics'
> >>> >>
> >>> >> The following objects are masked from 'package:stats':
> >>> >>
> >>> >> IQR, mad, sd, var, xtabs
> >>> >>
> >>> >> The following objects are masked from 'package:base':
> >>> >>
> >>> >> anyDuplicated, aperm, append, as.data.frame, basename, cbind,
> >>> >> colnames, dirname, do.call, duplicated, eval, evalq, Filter, Find,
> >>> >> get, grep, grepl, intersect, is.unsorted, lapply, Map, mapply,
> >>> >> match, mget, order, paste, pmax, pmax.int, pmin, pmin.int,
> >>> >> Position, rank, rbind, Reduce, rownames, sapply, saveRDS, setdiff,
> >>> >> table, tapply, union, unique, unsplit, which.max, which.min
> >>> >>
> >>> >> Welcome to Bioconductor
> >>> >>
> >>> >> Vignettes contain introductory material; view with
> >>> >> 'browseVignettes()'. To cite Bioconductor, see
> >>> >> 'citation("Biobase")', and for packages 'citation("pkgname")'.
> >>> >>
> >>> >>> library("SummarizedExperiment")
> >>> >> Loading required package: MatrixGenerics
> >>> >> Loading required package: matrixStats
> >>> >>
> >>> >> Attaching package: 'matrixStats'
> >>> >>
> >>> >> The following objects are masked from 'package:Biobase':
> >>> >>
> >>> >> anyMissing, rowMedians
> >>> >>
> >>> >>
> >>> >> Attaching package: 'MatrixGenerics'
> >>> >>
> >>> >> The following objects are masked from 'package:matrixStats':
> >>> >>
> >>> >> colAlls, colAnyNAs, colAnys, colAvgsPerRowSet, colCollapse,
> >>> >> colCounts, colCummaxs, colCummins, colCumprods, colCumsums,
> >>> >> colDiffs, colIQRDiffs, colIQRs, colLogSumExps, colMadDiffs,
> >>> >> colMads, colMaxs, colMeans2, colMedians, colMins, colOrderStats,
> >>> >> colProds, colQuantiles, colRanges, colRanks, colSdDiffs, colSds,
> >>> >> colSums2, colTabulates, colVarDiffs, colVars, colWeightedMads,
> >>> >> colWeightedMeans, colWeightedMedians, colWeightedSds,
> >>> >> colWeightedVars, rowAlls, rowAnyNAs, rowAnys, rowAvgsPerColSet,
> >>> >> rowCollapse, rowCounts, rowCummaxs, rowCummins, rowCumprods,
> >>> >> rowCumsums, rowDiffs, rowIQRDiffs, rowIQRs, rowLogSumExps,
> >>> >> rowMadDiffs, rowMads, rowMaxs, rowMeans2, rowMedians, rowMins,
> >>> >> rowOrderStats, rowProds, rowQuantiles, rowRanges, rowRanks,
> >>> >> rowSdDiffs, rowSds, rowSums2, rowTabulates, rowVarDiffs, rowVars,
> >>> >> rowWeightedMads, rowWeightedMeans, rowWeightedMedians,
> >>> >> rowWeightedSds, rowWeightedVars
> >>> >>
> >>> >> The following object is masked from 'package:Biobase':
> >>> >>
> >>> >> rowMedians
> >>> >>
> >>> >> Loading required package: GenomicRanges
> >>> >> Loading required package: stats4
> >>> >> Loading required package: S4Vectors
> >>> >>
> >>> >> Attaching package: 'S4Vectors'
> >>> >>
> >>> >> The following objects are masked from 'package:Matrix':
> >>> >>
> >>> >> expand, unname
> >>> >>
> >>> >> The following object is masked from 'package:utils':
> >>> >>
> >>> >> findMatches
> >>> >>
> >>> >> The following objects are masked from 'package:base':
> >>> >>
> >>> >> expand.grid, I, unname
> >>> >>
> >>> >> Loading required package: IRanges
> >>> >> Loading required package: GenomeInfoDb
> >>> >>> library("SingleCellExperiment")
> >>> >>> setClassUnion("ExpData", c("matrix", "dgCMatrix",
> >>> >> + "ExpressionSet", "SingleCellExperiment"))
> >>> >>> setGeneric("expShow", \(.) standardGeneric("expShow"))
> >>> >> [1] "expShow"
> >>> >>> setMethod("expShow", "ExpData", \(.) show(.))
> >>> >>> p <- 10
> >>> >>> n <- 30
> >>> >>> y <- matrix(rnorm(n*p), nrow=p, ncol=n,
> >>> >> + dimnames=list(
> >>> >> + paste("g", 1:p, sep="") ,
> >>> >> + paste("s", 1:n, sep="")))
> >>> >>> se <- SummarizedExperiment(y)
> >>> >>> sce <- SingleCellExperiment(y)
> >>> >>> expShow(se)
> >>> >> Error: unable to find an inherited method for function 'expShow' for
> >>> >> signature '. = "SummarizedExperiment"'
> >>> >>> expShow(sce)
> >>> >> class: SingleCellExperiment
> >>> >> dim: 10 30
> >>> >> metadata(0):
> >>> >> assays(1): ''
> >>> >> rownames(10): g1 g2 ... g9 g10
> >>> >> rowData names(0):
> >>> >> colnames(30): s1 s2 ... s29 s30
> >>> >> colData names(0):
> >>> >> reducedDimNames(0):
> >>> >> mainExpName: NULL
> >>> >> altExpNames(0):
> >>> >>>
> >>> >>>
> >>> >>> sessionInfo()
> >>> >> R version 4.4.2 (2024-10-31)
> >>> >> Platform: x86_64-pc-linux-gnu
> >>> >> Running under: Ubuntu 20.04.6 LTS
> >>> >>
> >>> >> Matrix products: default
> >>> >> BLAS: /home/axel/R/local/R-4.4.2/lib/libRblas.so
> >>> >> LAPACK: /home/axel/R/local/R-4.4.2/lib/libRlapack.so; LAPACK version 3.12.0
> >>> >>
> >>> >> locale:
> >>> >> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
> >>> >> [3] LC_TIME=es_ES.UTF-8 LC_COLLATE=en_US.UTF-8
> >>> >> [5] LC_MONETARY=es_ES.UTF-8 LC_MESSAGES=en_US.UTF-8
> >>> >> [7] LC_PAPER=es_ES.UTF-8 LC_NAME=C
> >>> >> [9] LC_ADDRESS=C LC_TELEPHONE=C
> >>> >> [11] LC_MEASUREMENT=es_ES.UTF-8 LC_IDENTIFICATION=C
> >>> >>
> >>> >> time zone: Europe/Madrid
> >>> >> tzcode source: system (glibc)
> >>> >>
> >>> >> attached base packages:
> >>> >> [1] stats4 stats graphics grDevices utils datasets methods
> >>> >> [8] base
> >>> >>
> >>> >> other attached packages:
> >>> >> [1] SingleCellExperiment_1.28.1 SummarizedExperiment_1.36.0
> >>> >> [3] GenomicRanges_1.58.0 GenomeInfoDb_1.42.1
> >>> >> [5] IRanges_2.40.1 S4Vectors_0.44.0
> >>> >> [7] MatrixGenerics_1.18.0 matrixStats_1.5.0
> >>> >> [9] Biobase_2.66.0 BiocGenerics_0.52.0
> >>> >> [11] Matrix_1.7-1
> >>> >>
> >>> >> loaded via a namespace (and not attached):
> >>> >> [1] R6_2.5.1 SparseArray_1.6.0 zlibbioc_1.52.0
> >>> >> [4] lattice_0.22-6 abind_1.4-8 GenomeInfoDbData_1.2.13
> >>> >> [7] S4Arrays_1.6.0 XVector_0.46.0 UCSC.utils_1.2.0
> >>> >> [10] fortunes_1.5-4 grid_4.4.2 DelayedArray_0.32.0
> >>> >> [13] compiler_4.4.2 httr_1.4.7 tools_4.4.2
> >>> >> [16] crayon_1.5.3 jsonlite_1.8.9
> >>> >>
> >>> >> Am Mi., 8. Jan. 2025 um 13:41 Uhr schrieb Helena L. Crowell <helena using crowell.eu>:
> >>> >>> SCE inherits from SE, but not vice versa. So setting the class union on SCE (not SE) will do the trick. Briefly, Anything defined on an SCE will work upstream (SE), but anything defined on SE will not work downstream (SPE, SCE).
> >>> >>>
> >>> >>> ***
> >>> >>>
> >>> >>> This works:
> >>> >>>
> >>> >>> library("Matrix")
> >>> >>> library("Biobase")
> >>> >>> library("SummarizedExperiment")
> >>> >>> library("SingleCellExperiment")
> >>> >>>
> >>> >>> setClassUnion("ExpData", c("matrix", "dgCMatrix",
> >>> >>> "ExpressionSet", "SingleCellExperiment"))
> >>> >>>
> >>> >>> setGeneric("expShow", \(.) standardGeneric("expShow"))
> >>> >>> setMethod("expShow", "ExpData", \(.) show(.))
> >>> >>>
> >>> >>> p <- 10
> >>> >>> n <- 30
> >>> >>> y <- matrix(rnorm(n*p), nrow=p, ncol=n,
> >>> >>> dimnames=list(
> >>> >>> paste("g", 1:p, sep="") ,
> >>> >>> paste("s", 1:n, sep="")))
> >>> >>>
> >>> >>> se <- SummarizedExperiment(y)
> >>> >>> sce <- SingleCellExperiment(y)
> >>> >>>
> >>> >>> expShow(se)
> >>> >>> expShow(sce)
> >>> >>>
> >>> >>>> On Jan 7, 2025, at 21:33, Axel Klenk <axel.klenk using gmail.com> wrote:
> >>> >>>>
> >>> >>>> Dear Community, dear S4 Experts,
> >>> >>>>
> >>> >>>> in the GSVA package I want to use an S4 class union as a superclass
> >>> >>>> for all supported data containers and S4 methods
> >>> >>>> defined for this superclass, rather than for each subclass, where a
> >>> >>>> class-specific implementation is not necessary. In particular
> >>> >>>> I want to avoid having to implement individual methods for all current
> >>> >>>> (and possibly, future) subclasses of SummarizedExperiment
> >>> >>>> for common operations like accessing assay names and dimensions, assay
> >>> >>>> data, etc.
> >>> >>>>
> >>> >>>> As you can see from the example code and output below, this works as
> >>> >>>> expected for SummarizedExperiment objects but not
> >>> >>>> for its subclasses such as SingleCellExperiment or SpatialExperiment
> >>> >>>> (if SummarizedExperiment is part of the class union and
> >>> >>>> the others are not). In the latter case the result is "Error: unable
> >>> >>>> to find an inherited method for function ..." (please see below).
> >>> >>>>
> >>> >>>> I'd be very grateful if someone with more S4 expertise than myself
> >>> >>>> could please let me know if and how this can be solved -- or
> >>> >>>> if the whole thing is not a good idea at all. ;-)
> >>> >>>>
> >>> >>>> Thanks a lot,
> >>> >>>>
> >>> >>>> - axel
> >>> >>>>
> >>> >>>>
> >>> >>>>
> >>> >>>> ### define a class union as a common superclass
> >>> >>>> library("Matrix")
> >>> >>>> library("Biobase")
> >>> >>>> library("SummarizedExperiment")
> >>> >>>> library("SingleCellExperiment")
> >>> >>>> ## [package startup messages omitted]
> >>> >>>>
> >>> >>>> setClassUnion("ExpData",
> >>> >>>> c("matrix", "dgCMatrix", "ExpressionSet", "SummarizedExperiment"))
> >>> >>>>
> >>> >>>> ### ... and an example method for the superclass
> >>> >>>> setGeneric("expShow", function(object) standardGeneric("expShow"))
> >>> >>>> setMethod("expShow",
> >>> >>>> signature=signature(object="ExpData"),
> >>> >>>> function(object) {
> >>> >>>> show(object)
> >>> >>>> })
> >>> >>>>
> >>> >>>> ### generate some example data and test the method:
> >>> >>>> p <- 10
> >>> >>>> n <- 30
> >>> >>>> y <- matrix(rnorm(n*p), nrow=p, ncol=n,
> >>> >>>> dimnames=list(paste("g", 1:p, sep="") , paste("s", 1:n, sep="")))
> >>> >>>>
> >>> >>>> se <- SummarizedExperiment(y)
> >>> >>>> show(se)
> >>> >>>> ## class: SummarizedExperiment
> >>> >>>> ## dim: 10 30
> >>> >>>> ## metadata(0):
> >>> >>>> ## assays(1): ''
> >>> >>>> ## rownames(10): g1 g2 ... g9 g10
> >>> >>>> ## rowData names(0):
> >>> >>>> ## colnames(30): s1 s2 ... s29 s30
> >>> >>>> ## colData names(0):
> >>> >>>>
> >>> >>>> expShow(se)
> >>> >>>> ## class: SummarizedExperiment
> >>> >>>> ## dim: 10 30
> >>> >>>> ## metadata(0):
> >>> >>>> ## assays(1): ''
> >>> >>>> ## rownames(10): g1 g2 ... g9 g10
> >>> >>>> ## rowData names(0):
> >>> >>>> ## colnames(30): s1 s2 ... s29 s30
> >>> >>>> ## colData names(0):
> >>> >>>>
> >>> >>>> sce <- SingleCellExperiment(y)
> >>> >>>> show(sce)
> >>> >>>> ## class: SingleCellExperiment
> >>> >>>> ## dim: 10 30
> >>> >>>> ## metadata(0):
> >>> >>>> ## assays(1): ''
> >>> >>>> ## rownames(10): g1 g2 ... g9 g10
> >>> >>>> ## rowData names(0):
> >>> >>>> ## colnames(30): s1 s2 ... s29 s30
> >>> >>>> ## colData names(0):
> >>> >>>> ## reducedDimNames(0):
> >>> >>>> ## mainExpName: NULL
> >>> >>>> ## altExpNames(0):
> >>> >>>>
> >>> >>>> expShow(sce)
> >>> >>>> ## Error: unable to find an inherited method for function 'expShow'
> >>> >>>> for signature 'object = "SingleCellExperiment"'
> >>> >>>>
> >>> >>>> ### ### ###
> >>> >>>>
> >>> >>>> ## we can define a new subclass of SummarizedExperiment in the global
> >>> >>>> environment that works -- as
> >>> >>>> ## long as it is not coerced to SingleCellExperiment
> >>> >>>>
> >>> >>>> setClass("expA",
> >>> >>>> contains="RangedSummarizedExperiment")
> >>> >>>>
> >>> >>>> ea <- new("expA")
> >>> >>>> show(ea)
> >>> >>>> ## An object of class "expA"
> >>> >>>> ## Slot "rowRanges":
> >>> >>>> ## GRanges object with 0 ranges and 0 metadata columns:
> >>> >>>> ## seqnames ranges strand
> >>> >>>> ## <Rle> <IRanges> <Rle>
> >>> >>>> ## -------
> >>> >>>> ## seqinfo: no sequences
> >>> >>>> ##
> >>> >>>> ## Slot "colData":
> >>> >>>> ## DataFrame with 0 rows and 0 columns
> >>> >>>> ##
> >>> >>>> ## Slot "assays":
> >>> >>>> ## NULL
> >>> >>>> ##
> >>> >>>> ## Slot "NAMES":
> >>> >>>> ## NULL
> >>> >>>> ##
> >>> >>>> ## Slot "elementMetadata":
> >>> >>>> ## DataFrame with 0 rows and 0 columns
> >>> >>>> ##
> >>> >>>> ## Slot "metadata":
> >>> >>>> ## list()
> >>> >>>>
> >>> >>>> expShow(ea)
> >>> >>>> ## class: SummarizedExperiment
> >>> >>>> ## dim: 0 0
> >>> >>>> ## metadata(0):
> >>> >>>> ## assays(0):
> >>> >>>> ## rownames: NULL
> >>> >>>> ## rowData names(0):
> >>> >>>> ## colnames: NULL
> >>> >>>> ## colData names(0):
> >>> >>>>
> >>> >>>> scea <- as(ea, "SingleCellExperiment")
> >>> >>>> show(scea)
> >>> >>>> ## class: SingleCellExperiment
> >>> >>>> ## dim: 0 0
> >>> >>>> ## metadata(0):
> >>> >>>> ## assays(0):
> >>> >>>> ## rownames: NULL
> >>> >>>> ## rowData names(0):
> >>> >>>> ## colnames: NULL
> >>> >>>> ## colData names(0):
> >>> >>>> ## reducedDimNames(0):
> >>> >>>> ## mainExpName: NULL
> >>> >>>> ## altExpNames(0):
> >>> >>>>
> >>> >>>> expShow(scea)
> >>> >>>> ## Error: unable to find an inherited method for function 'expShow'
> >>> >>>> for signature 'object = "SingleCellExperiment"'
> >>> >>>>
> >>> >>>> ### ### ### ### ###
> >>> >>>>
> >>> >>>> ## as shown below, SummarizedExperiment and ExpData "know" about their
> >>> >>>> inheritance relation but
> >>> >>>> ## SingleCellExperiment does not...
> >>> >>>>
> >>> >>>> getClass("SummarizedExperiment")
> >>> >>>> ## Class "SummarizedExperiment" [package "SummarizedExperiment"]
> >>> >>>> ##
> >>> >>>> ## Slots:
> >>> >>>> ##
> >>> >>>> ## Name: colData assays NAMES
> >>> >>>> elementMetadata metadata
> >>> >>>> ## Class: DataFrame Assays_OR_NULL character_OR_NULL
> >>> >>>> DataFrame list
> >>> >>>> ##
> >>> >>>> ## Extends:
> >>> >>>> ## Class "RectangularData", directly
> >>> >>>> ## Class "Vector", directly
> >>> >>>> ## Class "ExpData", directly
> >>> >>>> ## Class "Annotated", by class "Vector", distance 2
> >>> >>>> ## Class "vector_OR_Vector", by class "Vector", distance 2
> >>> >>>> ##
> >>> >>>> ## Known Subclasses:
> >>> >>>> ## Class "RangedSummarizedExperiment", directly, with explicit coerce
> >>> >>>>
> >>> >>>> getClass("ExpData")
> >>> >>>> ## Extended class definition ( "ClassUnionRepresentation" )
> >>> >>>> ## Virtual Class "ExpData" [in ".GlobalEnv"]
> >>> >>>> ##
> >>> >>>> ## No Slots, prototype of class "matrix"
> >>> >>>> ##
> >>> >>>> ## Known Subclasses:
> >>> >>>> ## Class "matrix", directly
> >>> >>>> ## Class "dgCMatrix", directly
> >>> >>>> ## Class "ExpressionSet", directly
> >>> >>>> ## Class "SummarizedExperiment", directly
> >>> >>>> ## Class "mts", by class "matrix", distance 2
> >>> >>>> ## Class "RangedSummarizedExperiment", by class
> >>> >>>> "SummarizedExperiment", distance 2, with explicit coerce
> >>> >>>>
> >>> >>>> getClass("SingleCellExperiment")
> >>> >>>> ## Class "SingleCellExperiment" [package "SingleCellExperiment"]
> >>> >>>> ##
> >>> >>>> ## Slots:
> >>> >>>> ##
> >>> >>>> ## Name: int_elementMetadata int_colData
> >>> >>>> int_metadata
> >>> >>>> ## Class: DataFrame DataFrame
> >>> >>>> list
> >>> >>>> ##
> >>> >>>> ## Name: rowRanges colData
> >>> >>>> assays
> >>> >>>> ## Class: GenomicRanges_OR_GRangesList DataFrame
> >>> >>>> Assays_OR_NULL
> >>> >>>> ##
> >>> >>>> ## Name: NAMES elementMetadata
> >>> >>>> metadata
> >>> >>>> ## Class: character_OR_NULL DataFrame
> >>> >>>> list
> >>> >>>> ##
> >>> >>>> ## Extends:
> >>> >>>> ## Class "RangedSummarizedExperiment", directly
> >>> >>>> ## Class "SummarizedExperiment", by class
> >>> >>>> "RangedSummarizedExperiment", distance 2
> >>> >>>> ## Class "RectangularData", by class "RangedSummarizedExperiment", distance 3
> >>> >>>> ## Class "Vector", by class "RangedSummarizedExperiment", distance 3
> >>> >>>> ## Class "Annotated", by class "RangedSummarizedExperiment", distance 4
> >>> >>>> ## Class "vector_OR_Vector", by class "RangedSummarizedExperiment", distance 4
> >>> >>>>
> >>> >>>> ### ### ### ### ###
> >>> >>>>
> >>> >>>> getClass("SummarizedExperiment")
> >>> >>>> ## Class "SummarizedExperiment" [package "SummarizedExperiment"]
> >>> >>>> ##
> >>> >>>> ## Slots:
> >>> >>>> ##
> >>> >>>> ## Name: colData assays NAMES
> >>> >>>> elementMetadata metadata
> >>> >>>> ## Class: DataFrame Assays_OR_NULL character_OR_NULL
> >>> >>>> DataFrame list
> >>> >>>> ##
> >>> >>>> ## Extends:
> >>> >>>> ## Class "RectangularData", directly
> >>> >>>> ## Class "Vector", directly
> >>> >>>> ## Class "ExpData", directly
> >>> >>>> ## Class "Annotated", by class "Vector", distance 2
> >>> >>>> ## Class "vector_OR_Vector", by class "Vector", distance 2
> >>> >>>> ##
> >>> >>>> ## Known Subclasses:
> >>> >>>> ## Class "RangedSummarizedExperiment", directly, with explicit coerce
> >>> >>>> ## Class "expA", by class "RangedSummarizedExperiment", distance 2,
> >>> >>>> with explicit coerce
> >>> >>>>
> >>> >>>> getClass("expA")
> >>> >>>> ## Class "expA" [in ".GlobalEnv"]
> >>> >>>> ##
> >>> >>>> ## Slots:
> >>> >>>> ##
> >>> >>>> ## Name: rowRanges colData
> >>> >>>> assays
> >>> >>>> ## Class: GenomicRanges_OR_GRangesList DataFrame
> >>> >>>> Assays_OR_NULL
> >>> >>>> ##
> >>> >>>> ## Name: NAMES elementMetadata
> >>> >>>> metadata
> >>> >>>> ## Class: character_OR_NULL DataFrame
> >>> >>>> list
> >>> >>>> ##
> >>> >>>> ## Extends:
> >>> >>>> ## Class "RangedSummarizedExperiment", directly
> >>> >>>> ## Class "SummarizedExperiment", by class
> >>> >>>> "RangedSummarizedExperiment", distance 2, with explicit coerce
> >>> >>>> ## Class "RectangularData", by class "RangedSummarizedExperiment", distance 3
> >>> >>>> ## Class "Vector", by class "RangedSummarizedExperiment", distance 3
> >>> >>>> ## Class "ExpData", by class "RangedSummarizedExperiment", distance 3,
> >>> >>>> with explicit coerce
> >>> >>>> ## Class "Annotated", by class "RangedSummarizedExperiment", distance 4
> >>> >>>> ## Class "vector_OR_Vector", by class "RangedSummarizedExperiment", distance 4
> >>> >>>>
> >>> >>>> getClass("SingleCellExperiment")
> >>> >>>> ## Class "SingleCellExperiment" [package "SingleCellExperiment"]
> >>> >>>> ##
> >>> >>>> ## Slots:
> >>> >>>> ##
> >>> >>>> ## Name: int_elementMetadata int_colData
> >>> >>>> int_metadata
> >>> >>>> ## Class: DataFrame DataFrame
> >>> >>>> list
> >>> >>>> ##
> >>> >>>> ## Name: rowRanges colData
> >>> >>>> assays
> >>> >>>> ## Class: GenomicRanges_OR_GRangesList DataFrame
> >>> >>>> Assays_OR_NULL
> >>> >>>> ##
> >>> >>>> ## Name: NAMES elementMetadata
> >>> >>>> metadata
> >>> >>>> ## Class: character_OR_NULL DataFrame
> >>> >>>> list
> >>> >>>> ##
> >>> >>>> ## Extends:
> >>> >>>> ## Class "RangedSummarizedExperiment", directly
> >>> >>>> ## Class "SummarizedExperiment", by class
> >>> >>>> "RangedSummarizedExperiment", distance 2
> >>> >>>> ## Class "RectangularData", by class "RangedSummarizedExperiment", distance 3
> >>> >>>> ## Class "Vector", by class "RangedSummarizedExperiment", distance 3
> >>> >>>> ## Class "Annotated", by class "RangedSummarizedExperiment", distance 4
> >>> >>>> ## Class "vector_OR_Vector", by class "RangedSummarizedExperiment", distance 4
> >>> >>>>
> >>> >>>> _______________________________________________
> >>> >>>> Bioc-devel using r-project.org mailing list
> >>> >>>> https://stat.ethz.ch/mailman/listinfo/bioc-devel
> >>> >>>>
> >>> > _______________________________________________
> >>> > Bioc-devel using r-project.org mailing list
> >>> > https://stat.ethz.ch/mailman/listinfo/bioc-devel
> >>>
> >>> --
> >>> Hervé Pagès
> >>>
> >>> Bioconductor Core Team
> >>> hpages.on.github using gmail.com
> >>>
> >>> _______________________________________________
> >>> Bioc-devel using r-project.org mailing list
> >>> https://stat.ethz.ch/mailman/listinfo/bioc-devel
> >>
> >>
> >>
> >> --
> >> Best,
> >> Kasper
>
> > _______________________________________________
> > Bioc-devel using r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/bioc-devel
More information about the Bioc-devel
mailing list