[R-pkg-devel] Strange behaviour of function called from within a function

J C Nash pro|jcn@@h @end|ng |rom gm@||@com
Sat Aug 13 00:40:39 CEST 2022


I have been trying to sort out an odd issue for the last few days in upgrading package
nlsr (for nonlinear least squares). It generally does much better in finding solutions from
poor starts than nls(), but it does not generate the full nls returned object. I've written a
wrapper wrapnlsr() that calls my nlsr functions then uses the resulting parameters in nls()
to get the nls object. But up to now, neither weights nor subset are allowed. I've not got
to subset, but have been trying weights, with very strange results. The full example is too
much code for the list, so I've faked the nlsr output as "firstcoef" in the example below.
What is troubling is that a hand-run example "works", but using a function to do it fails
when there are weights.

The nls.R code referenced in the example around line 570 may suggest that its handling the
weights may be the culprit here. I don't understand why
     eval(substitute(weights), data, environment(formula))
is needed for a fixed numeric vector of weights (as required by the manual).

Any help welcome.

John Nash

The example:

# wterr.R -- reproduce nls error when called from function
rm(list=ls()) # probably not needed, but clear the workspace

tnow <- function(formula, data, start, control, trace) {
   firstcoef <- c(b1=199, b2=50, b3=0.3) # as if from another solver
   cat("firstcoef:\n")
   print(firstcoef)
   cat("No weights\n")
   second<-nls(formula, data, firstcoef, control, algorithm=NULL, TRUE)
   second
}

tw <- function(formula, data, start, control, trace, weights) {
   firstcoef <- c(b1=199, b2=50, b3=0.3)
   cat("firstcoef:\n")
   print(firstcoef)
   cat("weights:"); print(weights)
   secondw<-nls(formula, data, firstcoef, control, algorithm=NULL, TRUE, weights=weights)
   secondw
}

weed <- c(5.308, 7.24, 9.638, 12.866, 17.069, 23.192, 31.443,
           38.558, 50.156, 62.948, 75.995, 91.972)
tt <- 1:12
weeddf <- data.frame(tt, weed)
hobbsu <- weed ~ b1/(1+b2*exp(-b3*tt))
st2 <- c(b1=200, b2=50, b3=0.3)
wts <- 0.5^tt # a straight scaling comes via wts <- rep(0.01, 12)
# From this level, we can do the calculation
firstcoef <- c(b1=199, b2=50, b3=0.3)

# Does NOT work from the function tw with weights, but unweighted OK.
# Is the issue line 570/571 of ./R-4.2.1/src/library/stats/R/nls.R ??
tn2<-tnow(hobbsu, weeddf, st2, control=list(), trace=TRUE)
tn2
tt2<-tw(hobbsu, weeddf, st2, control=list(), trace=TRUE, weights=wts)
tt2

# But we can get it running directly
formula<-hobbsu
data<-weeddf
control<-list()
weights<-wts
second<-nls(formula, data, firstcoef, control, algorithm=NULL, TRUE)
second
secondw<-nls(formula, data, firstcoef, control, algorithm=NULL, TRUE, weights=weights)
secondw
# And if we rerun the functions AFTER succeeding here, tw now works
tn2<-tnow(hobbsu, weeddf, st2, control=list(), trace=TRUE)
tn2
tt2<-tw(hobbsu, weeddf, st2, control=list(), trace=TRUE, weights=wts)
tt2



More information about the R-package-devel mailing list