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
<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

Reply via email to