On 16/10/2018 6:42 PM, Therneau, Terry M., Ph.D. via R-devel
wrote:> The survival package, like many others, has several helper functions that
are not declared
> in the namespace, since their only use is to be called by other
"main" functions of the
> package.? This works well since the functions in the survival namespace can
see them ---
> without ::: arguments --- and others don't.
>
> Until a situation I ran into this week, for which I solicit comments or
advice.?? The
> concordance function is a new addition, and it has one case where the same
underlying
> helper function is called multiple times, with many arguments passed
through from the
> parent.? I thought that this would be a good use for the trick we use for
model.frame, so
> I have code like this:
>
> concordance.coxph <- function(fit, ..., newdata, group, ymin, ymax,
> ?????????????????????????????? timewt=c("n", "S",
"S/G", "n/G", "n/G2"),
> ?????????????????????????????? influence=0, ranks=FALSE, timefix=TRUE) {
> ??? Call <- match.call()
> ??? .
> ??? .
> ??? .
> ??? cargs <- c("ymin",
"ymax","influence", "ranks", "timewt",
"timefix")
> ??? cfun <- Call[c(1, match(cargs, names(Call), nomatch=0))]
> ??? cfun[[1]] <- quote(cord.work)
> ??? cfun$reverse <- TRUE
> ??? rval <- eval(cfun, parent.frame())
>
> This worked fine in my not-in-a-namespace test bed, but then fails when
packaged up for
> real: the code can't find the helper function cord.work!? The rule that
survival package
> functions can "see" their undeclared helpers fails.
The reason that fails is as follows:
cfun, despite its name, is not a function. It's an unevaluated expression.
You are evaluating it in parent.frame(), which is the caller's
evaluation frame. That frame can't generally see the private frame for
your package.
Since it needs to see things supplied by the user, it needs to see
parent.frame. It doesn't need to see anything in your evaluation frame
other than cord.work, but it can't see that, which is your problem.
I think there are at least two choices:
1. change cfun[[1]] <- quote(cord.work) to cfun[[1]] <- cord.work.
This should work, but error messages may be messed up, because you'll be
calling an anonymous function that is a copy of cord.work, rather than
calling cord.work by name.
2. change cfun[[1]] <- quote(cord.work) to cfun[[1]] <-
quote(survival:::cord.work). You say this will mess up your test bed.
That suggests that your test bed is broken. This is a perfectly legal
and valid solution.
Duncan Murdoch
>
> I got it working by changing parent.frame() to environment(concordance) in
the eval()
> call.?? Since everything used by cord.work is explicitly passed in its
argument list this
> does work.
>
> Comments or suggestions??? (I avoid having survival:: in the survival
package because it
> messes up my particular test bed.)
>
> Terry
>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>