>>>>> Axel Klenk >>>>> on Thu, 23 Jan 2025 15:31:18 +0100 writes:
> 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 a lot, Axel, for your reproducible example. and so, as I am also one of the recipients of the R bugzilla applications, I was wondering why we have not yet received yours ... > Thanks to all for your help so far and any additional > advice, > - axel Indeed, notably thanks for your own help by reducing the example! Ideally your packages could become even much smaller (to be added to a test suite in the future): - no LICENSE, README.md nor man/ - no 'Depends:' in DESCRIPTION, only 'Imports: methods' - in NAMESPACE, wrt methods, you'd only have importFrom(methods, setClass) Best, Martin > Am Mi., 15. Jan. 2025 um 09:08 Uhr schrieb Martin Maechler > <maech...@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 > <kasperdanielhan...@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.git...@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.kl...@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 <hel...@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.kl...@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@r-project.org mailing list >>> >>>> >> https://stat.ethz.ch/mailman/listinfo/bioc-devel >> >>> >>>> >> >>> > _______________________________________________ >>> >> > Bioc-devel@r-project.org mailing list >>> > >> https://stat.ethz.ch/mailman/listinfo/bioc-devel >> >>> >> >>> -- >> >>> Hervé Pagès >> >>> >> >>> Bioconductor Core Team >>> hpages.on.git...@gmail.com >> >>> >> >>> _______________________________________________ >>> >> Bioc-devel@r-project.org mailing list >>> >> https://stat.ethz.ch/mailman/listinfo/bioc-devel >> >> >> >> >> >> >> >> -- >> >> Best, >> Kasper >> >> > _______________________________________________ > >> Bioc-devel@r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/bioc-devel _______________________________________________ Bioc-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/bioc-devel