>>>>> "MH" == Michael Hahsler <mich...@hahsler.net> >>>>> on Mon, 20 Jul 2009 08:57:28 -0500 writes:
MH> Hi, I'm trying to create a new S4 class (myMatrix) which MH> for now just extends dgCMatrix (from package MH> Matrix). Then I want to use "[" which is defined in MH> Matrix. MH> Out of the box with "[" (defined in Matrix) I lose the MH> class information and the result is an object of class MH> dgCMatrix. Yes, and that's the case for all such methods for "extended" classes, for S3 / S4 methods alike. Yes, this is sometimes not what you would like, and on R-devel we recently had proposals on definining special attributes (for dataframe / matrix like objects) that would automatically be preserved in "[i,j]" subsetting.... so others had had similar wishes / dreams. As I have learned in similar experience, it's not a good idea to expect that this happens automatically. Assume "myMatrix" was meant to always be a square matrix, or always a symmetric matrix. Then, only *some* "[i,j]" operations would return a valid "myMatrix"... For such reasons, indeed, it's you who must provide methods for your class. Of couese these methods will typically call the "upper class" method, possibly via callNextMethod(.), or {my historical preference} directly. MH> If I specify a "["-method for myMatrix, it is MH> not used because a signature from Matrix seems to fit MH> better. Yes, Matrix" has many methods for "[", for good reasons, but if you define your methods "correctly", things are solved easily, see below MH> However, the most important part of the MH> signature is the class of x (all else have ANY). Is MH> there a way to specify a single "["-method do make it MH> work for myClass? a single method is not sufficient; "[" is a generic function with several signauture arguments, on which dispatch can happen. And note, that "[" is particularly delicate : The code (well, the one in "Matrix") must be able to distinguish between M[ i,] and M[ i ] Here's a working solution: --------------------------------------------------------------- library("Matrix") setClass("myMatrix", contains="dgCMatrix") M <- as(Diagonal(x = 1:7), "CsparseMatrix") (my <- as(as(M, "dgCMatrix"), "myMatrix")) ## here I lose the class "myMatrix" class(my[1:2,]) ## [1] "dgCMatrix" ## make sure [ keeps the class if(FALSE)# not really needed setMethod("[", signature(x = "myMatrix"), ## (ANY,ANY...) function(x, i, j, ..., drop) as(as(x,"dgCMatrix")[i, j, ..., drop], "myMatrix")) setMethod("[", signature(x = "myMatrix", i="index", j="index", drop="logical"), function(x, i, j, ..., drop) as(as(x,"dgCMatrix")[i, j, drop=drop], "myMatrix")) setMethod("[", signature(x = "myMatrix", i="index", j = "missing", drop="logical"), function(x, i, j, ..., drop) as(as(x,"dgCMatrix")[i, , drop=drop], "myMatrix")) setMethod("[", signature(x = "myMatrix", i = "missing", j="index",drop="logical"), function(x, i, j, ..., drop) as(as(x,"dgCMatrix")[ , j, drop=drop], "myMatrix")) head(my, 2) ## perfect my[3,3,drop=FALSE] # ditto my[, 2:4] # ditto --------------------------------------------------------------- Note that the three method definitions use slightly different function bodies: When an argument is "missing", it's not a good idea to pass it again to the generic "[" which then again would like to do method dispatch on that missing... Also, if you replace "index" (the indexing class introduced in 'Matrix", but more generally interesting) by "ANY", you need another methods definition in order to match to you "myMatrix" class first, before any of the many specific methods in "Matrix"..... Note further, that at the DSC 2007, I already noted a similar situation and had prposed back then, that it would be desirable to allow the programmer to more closely to specify method dispatch in a case like yours: We would want to specify that for method dispatch, the class of "x" (i.e. "myMatrix" in your case) should weight much more than the classes of (i,j,drop). But something like this has to wait for the future, ..... I hope this helped so far. >> library("Matrix") [.......] >> >> setClass("myMatrix", MH> + contains="dgCMatrix" MH> + ) {{why 3 lines instead of 1 ?}} MH> [1] "myMatrix" >> >> my <- as(as(rbind(1:10,1:10,1:10), "dgCMatrix"), "myMatrix") >> >> ## here I lose the class "myMatrix" >> class(my[1:2,]) MH> [1] "dgCMatrix" MH> attr(,"package") MH> [1] "Matrix" >> >> ## make sure [ keeps the class >> setMethod("[", signature(x = "myMatrix", i = "ANY", j = "ANY", MH> + drop = "ANY"), MH> + function(x, i, j, ..., drop) { MH> + x<- as(x, "dgCMatrix")[i, j, ..., drop] MH> + as(x, "myMatrix") MH> + }) MH> [1] "[" >> >> ## and now it does not use the method defined above. >> class(my[1:2,]) MH> Note: Method with signature "Matrix#index#missing#missing" chosen for MH> function "[", MH> target signature "myMatrix#integer#missing#missing". MH> "myMatrix#ANY#ANY#ANY" would also be valid MH> Note: Method with signature "sparseMatrix#index#missing#logical" chosen MH> for function "[", MH> target signature "myMatrix#integer#missing#logical". MH> "myMatrix#ANY#ANY#ANY" would also be valid MH> [1] "dgCMatrix" MH> attr(,"package") MH> [1] "Matrix" >> sessionInfo() MH> R version 2.9.1 (2009-06-26) MH> i486-pc-linux-gnu MH> locale: MH> LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=C;LC_MESSAGES=en_US.UTF-8;LC_PAPER=en_US.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C MH> attached base packages: MH> [1] stats graphics grDevices utils datasets methods base MH> other attached packages: MH> [1] Matrix_0.999375-29 lattice_0.17-25 MH> loaded via a namespace (and not attached): MH> [1] grid_2.9.1 MH> -- MH> Michael Hahsler MH> email: mich...@hahsler.net MH> web: http://michael.hahsler.net MH> ______________________________________________ MH> R-help@r-project.org mailing list MH> https://stat.ethz.ch/mailman/listinfo/r-help MH> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html MH> and provide commented, minimal, self-contained, reproducible code. ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.