[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