"Yang, Richard" <dyang@NRCan.gc.ca> writes:
> I experienced difficulties porting the SSweibull function in R to S (Splus 6
> or 2000). The code looks like the following:
>
> >wb <- deriv( ~ Asym - Drop*exp(-exp(lrc)*x^pwr), c("Asym", "Drop",
> "lrc", "pwr"),
> function(x, Asym, Drop, lrc, pwr) {})
>
> >wbInit <- ## from Dr. Doug Bates
> function (mCall, data, LHS)
> {
> xy <- sortedXyData(mCall[["x"]], LHS, data)
> if (nrow(xy) < 5) {
> stop("Too few distinct input values to fit the Weibull growth
> model")
> }
> if (any(xy[["x"]] < 0)) {
> error("All x values must be non-negative to fit the Weibull growth
> model")
> }
> Rasym <- NLSstRtAsymptote(xy)
> Lasym <- NLSstLfAsymptote(xy)
> pars <- coef(lm(log(-log((Rasym - y)/(Rasym - Lasym))) ~
> log(x), data = xy, subset = x > 0))
> val <- coef(nls(y ~ cbind(1, -exp(-exp(lrc) * x^pwr)), data = xy,
> alg = "plinear", start = c(lrc = pars[[1]], pwr = pars[[2]])))[c(3,
> 4, 1, 2)]
> names(val) <- mCall[c("Asym", "Drop", "lrc", "pwr")]
> val
> }
>
> >SSwb <- selfStart(wb, initial = wbInit)
>
> Following the creation of SSwb selfStart function, a test with the Orange
> data resulted in an error:
>
> > getInitial(circumference ~ SSwb(age, Asym, Drop, lrc, pwr), data =
>
> Orange)
> Error: Object "Rasym" not found
>
> It sounded like the NLSstRtsymptote() was not working. However,
>
> >Orange.sortAvg <- sortedXyData("age", "circumference", Orange)
>
> >NLSstRtAsymptote(Orange.sortAvg)
> >[1] 193.9
> > NLSstLfAsymptote(Orange.sortAvg)
> >[1] 12.9
>
> The SSweibull function works fine with the Orange dataset in R, but the same
> error occurred in both Splus 6 and Splus 2000.
>
> What did I miss? Please advise.
This is due to the differences in "scoping" in R and S-PLUS. Because
R uses evaluation environments that can nest, the call to lm in
pars <- coef(lm(log(-log((Rasym - y)/(Rasym - Lasym))) ~
log(x), data = xy, subset = x > 0))
sees the values of Rasym and Lasym that are assigned as
Rasym <- NLSstRtAsymptote(xy)
Lasym <- NLSstLfAsymptote(xy)
in the environment of the calling function.
In S-PLUS you must make the assignments in a frame that will be
visible during the evaluation of the lm function. The most convenient
such frame is frame 1, the expression evaluation frame. Replace those
assignments with
assign("Rasym", NLSstRtAsymptote(xy), frame = 1)
assign("Lasym", NLSstLfAsymptote(xy), frame = 1)
See the italicized section "The S scope rules" on page 60 of Venables
and Ripley, "S Programming" (Springer, 2000).
|