Skip to content

Baffled with as.matrix

2 messages · Terry Therneau, Brian Diggs

#
I'm puzzled by as.matrix.  It appears to work differently for Surv objects.
Here is a session from my computer:

tmt% R --vanilla
 > library(survival)
Loading required package: splines
 > ytest <- Surv(1:3, c(1,0,1))
 > is.matrix(ytest)
 >[1] TRUE

 > attr(ytest, 'type')
[1] "right"
 > attr(as.matrix(ytest), 'type')
[1] "right"
 >
 > y2 <- ytest
 > class(y2) <- "charlie"
 > as.matrix.charlie <- survival:::as.matrix.Surv
 > attr(y2, 'type')
[1] "right"
 > attr(as.matrix(y2), 'type')
NULL

 > survival:::as.matrix.Surv
function (x)
{
     y <- unclass(x)
     attr(y, "type") <- NULL
     y
}
<bytecode: 0x91c1610>
<environment: namespace:survival>

--------
It appears that Surv objects are being processed by as.matrix.default, but "charlie" 
objects by the
actual method.  One more verification:

 > attr(survival:::as.matrix.Surv(ytest), 'type')
NULL
 > attr(as.matrix.default(y2), 'type')
[1] "right"

Context: In testing the next survival release (2.37), it has lost this "special" 
behavior.  One package that depends on survival expects this behavior and thus fails.  I'm 
at a loss to figure out how my package got this attribute in the first place, or how it 
lost it.  Can anyone shed light?

Terry Therneau

PS I'm on vacation for the next few days so will be intermittent with email.  (Off to see 
my first grandchild!)

---------------------

 > sessionInfo()
R version 2.15.2 (2012-10-26)
Platform: i686-pc-linux-gnu (32-bit)

locale:
  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=C
  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
  [7] LC_PAPER=C                 LC_NAME=C
  [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] splines   stats     graphics  grDevices utils     datasets  methods
[8] base

other attached packages:
[1] survival_2.36-14
#
On 11/30/2012 4:53 AM, Terry Therneau wrote:
It seems that survival:::as.matrix.Surv is not recognized as a 
dispatch-able method for as.matrix:

 > methods("as.matrix")
[1] as.matrix.data.frame as.matrix.default    as.matrix.dist*
[4] as.matrix.noquote    as.matrix.POSIXlt    as.matrix.raster*
[7] as.matrix.ratetable*

I'm guessing it is not declared as such in the NAMESPACE file.
This new function does show up:

 > methods("as.matrix")
[1] as.matrix.charlie    as.matrix.data.frame as.matrix.default
[4] as.matrix.dist*      as.matrix.noquote    as.matrix.POSIXlt
[7] as.matrix.raster*    as.matrix.ratetable*

and is being called as expected.
What is being called by as.matrix(ytest) is as.matrix.default

 > as.matrix.default
function (x, ...)
{
     if (is.matrix(x))
         x
     else array(x, c(length(x), 1L), if (!is.null(names(x)))
         list(names(x), NULL)
     else NULL)
}
<bytecode: 0x000000000631a0b8>
<environment: namespace:base>

which will just return ytest is is.matrix(ytest) is TRUE (as you show).
Correct.
The behavior I showed above was with 2.36-14, even.

In your NAMESPACE file, there are two lines that say

S3method(as.matrix, ratetable)

I bet one of them was meant to be

S3method(as.matrix, Surv)