s-news
[Top] [All Lists]

Re: Problems porting R selfStart SSweibull to S

To: "Yang, Richard" <dyang@NRCan.gc.ca>
Subject: Re: Problems porting R selfStart SSweibull to S
From: Douglas Bates <bates@stat.wisc.edu>
Date: 21 Nov 2001 14:27:10 -0600
Cc: "'s-news@lists.biostat.wustl.edu'" <s-news@lists.biostat.wustl.edu>
In-reply-to: <F0E0B899CB43D5118D220002A55113CF21BA14@S2-EDM-R1>
References: <F0E0B899CB43D5118D220002A55113CF21BA14@S2-EDM-R1>
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7
"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).

<Prev in Thread] Current Thread [Next in Thread>