On Fri, Mar 7, 2014 at 6:46 AM, Therneau, Terry M., Ph.D.
<therneau at mayo.edu> wrote:>>> The help page for the survfit function says it expects a formula as
its
>>> first argument so try:
>>>
>>> > sleepfit <- survfit(Surv(timeb, death)~1, data = sleep)
>>>
>>> David
>>> Sent from my iPhone ... so unable to test.
>>>
>>>
>> This was a recent (well, 2007) change in behaviour. Previously the
>> function
>> did some tricks to make either approach work, which could be described
as
>> 'clever' or 'too clever by half'.
>>
>> -thomas
>
>
> Certainly the latter, a design mistake that I finally admitted and
> corrected. The trouble is this usage
> fit <- survfit(Surv(time, status), data=mine)
>
> The data, subset, weights, and na.action arguments are all meant to work
> with formulas. The first argument above isn't a formula. This left
survfit
> with the quandry of how to recognize that the first argument is a
"Surv"
> object and not a formula, and do something differently. Which leads to a
> stalemate
> a. One doesn't know what type of object the first argument is
until
> it is evaluated
> b. Evaluation will fail, however, unless it is evaluated in the
> "data=mine" context
> c. The function that does that process (model.frame) expects a
> formula as its first arg
>
> My program needed to know the answer to a) in order to transform the first
> arg into a formula and correctly execute c), but needed the answer from c)
> to know if that was necessary.
>
> The old code peeked back at the actual string that was typed by the user,
> looking for the letters "Surv", but was easily fooled.
It's not possible to be perfect in this scenario, but you could use
some heuristics:
survfit <- function(x, ...) {
xq <- substitute(x)
if (!is.call(xq)) {
stop("First argument to survfit must be a function call")
}
if (identical(xq[[1]], quote(Surv))) {
"surv"
} else if (identical(xq[[1]], quote(`~`))) {
"formula"
} else {
"don't know"
}
}
survfit(Surv(time, status), data=mine)
survfit(Surv(timeb, death)~1, data = sleep)
You'd need a different heuristic if is.name(xq) is TRUE, indicating
that the user passed in the name of an existing variable.
Hadley
--
http://had.co.nz/