[R] Error generated by nlme::gnls

Ivan Krylov kry|ov@r00t @end|ng |rom gm@||@com
Sun Jul 24 14:57:25 CEST 2022

Sorry for being too terse in my previous e-mail!

On Sun, 24 Jul 2022 23:03:02 +1200
Rolf Turner <r.turner using auckland.ac.nz> wrote:

> The maintainer of the nlme package (who is, according to maintainer(),
> "R-core") could change the code so that it uses invokes deparse1()
> rather than deparse, but the user cannot do so, not without in effect
> re-creating the package.

You're right. I think there's a buglet in nlme::gnls that nobody
noticed until R 4.2.0 was released *and* Aaron Crowley used the
function with a sufficiently long formula.

> Also, the question remains:  why did Aaron Crowley's code work in the
> past, whereas now it throws an error?  What changed?

gnls() may have been performing the `if (deparse(...) != '1')` test for
a long time, but never crashed before because it wasn't a fatal error
until R 4.2.0. Previously, if() would issue a warning and use the first
element of the boolean vector.

R 4.2.0 was released this April, which was less than 6 months ago. I
think it all fits.

A temporary solution would be to make use of the fact that R is a very
dynamic language and perform surgery on a live function inside a loaded


nlme <- loadNamespace('nlme')
unlockBinding('gnls', nlme)
nlme$gnls <- `body<-`(fun = nlme$gnls, value = walkCode(
	body(nlme$gnls), makeCodeWalker(
		call = function(e, w)
			as.call(lapply(as.list(e), function(ee)
				if (!missing(ee)) walkCode(ee, w)
		leaf = function(e, w)
			if (is.symbol(e) && e == 'deparse') {
			} else e
lockBinding('gnls', nlme)

grep('deparse', deparse(nlme::gnls), value = TRUE)
# [1] "                deparse1(pp[[3]]), sep = \"~\"), collapse =
\",\"), " # [2] "        if (deparse1(params[[nm]][[3]]) != \"1\") {"
# [3] "        list(row.names(dataModShrunk), deparse1(form[[2]]))), "

Aaron's example seems to work after this, modulo needing 12 starting
values instead of 13.

Best regards,

More information about the R-help mailing list