[R] str and Surv objects

Martin Maechler maechler at stat.math.ethz.ch
Wed Aug 11 10:13:08 CEST 2004


>>>>> "Laura" == Laura Holt <lauraholt_983 at hotmail.com>
>>>>>     on Tue, 10 Aug 2004 20:59:35 -0500 writes:

    Laura> Dear R People:
    Laura> I used the "Surv" function to produce the following object:
    >> a <- Surv(1:4,2:5,c(0,1,1,0)) 
    >> a
    Laura> [1] (1,2+] (2,3 ] (3,4 ] (4,5+]
    >> str(a)
    Laura> Error in "[.Surv"(object, 1:ile) : subscript out of bounds


    Laura> Why does str(a) give an error, please?  

because it assumes something that is probably true for (almost?)
all but these somewhat `crazy' Surv objects
{and that's not the "fault" of Thomas Lumley, the maintainer of
 "survival" for R, but rather the original 'survival' authors for S}:

## On one hand,  a  fulfills  
 is.array(a) & is.atomic(a) ## TRUE

 length(a) ## gives 12
	   ## but
 a[1:12]   ## gives an error and all a[k]  for k > 4 give errors
 length(as.character(a)) ## gives 4


so, I'll have to work around this problem in str.default()
and think about writing a  str.Surv()  (S3) method which would
be cleaner [code proposals for the latter are welcome, on R-devel, or to me!]

    Laura> Or did I do something wrong?

no you didn't.  You've discovered a bug -- I wonder why that
hasn't been found before.
It must be almost as old as R, well at least as old as these
[class="Surv", type="counting"] objects exist in the survival
package.

Here is the patch to the source in "R-patched",
"R-devel" will get a slightly different patch, if not
and str.Surv() method.

--- src/library/utils/R/str.R	(revision 30602)
+++ src/library/utils/R/str.R	(working copy)
@@ -247,9 +247,13 @@
 		ob <- if(le > iv.len) object[seq(len=iv.len)] else object
 		ao <- abs(ob <- ob[!is.na(ob)])
 	    }
+            else if(iSurv)
+                le <- length(object <- as.character(object))
 	    if(int.surv || (all(ao > 1e-10 | ao==0) && all(ao < 1e10| ao==0) &&
 			    all(ob == signif(ob, digits.d)))) {
-		v.len <- iv.len
+		if(!(iSurv && a$type == "counting"))
+                    ## use integer-like length
+                    v.len <- iv.len
 		format.fun <- function(x)x
 	    } else {
 		v.len <- round(1.25 * v.len)




More information about the R-help mailing list