# Problem defining non-linear formula

I wish to model effects of different predictors on different parameters of a logistic distribution
y=asym/(1+exp((midy-time)/halft))

I want the asym parameter to have the lognormal distribution, the midy parameter to have a normal distribution and the halft parameter to be lognormal (to constrain asym and halft to be positive). I want to allow random intercepts for each parameter

So, I tried defining the brms formula, thus:
bflog=nlf(asym~x1+(1|g)+lognormal()) + nlf(midy~x2+(1|g)) + nlf(halft~x3+(1|g)+lognormal()) + nlf(y~asym/(1+exp((midy-xt)/halft))) + set_nl(TRUE)

But this gives the error:
Error in nlf(asym ~ x1 + (1 | g) + lognormal()) + nlf(midy ~ x2 + (1 | :
non-numeric argument to binary operator

Each component is, by itself, OK. So, R accepts the following code without error.
f1=nlf(asym~x1+(1|g)+lognormal())
f2=nlf(midy~x2+(1|g))
f3=nlf(halft~x3+(1|g)+lognormal())
f4=nlf(y~asym/(1+exp((midy-xt)/halft)))

But, bflog=f1+f2+f3+f4 gives the same error as before:-
Error in f1 + f2 : non-numeric argument to binary operator

I’d be very grateful for guidance on how to construct the non-linear formula

I am running 2.13.0 on Windows 10

Can you provided a small example with the data you have so we can pinpoint this?

Well, I can create a toy data-set. But, the problem lies in the creation of the formula - which does not involve the data. So, I get the same error with or without data present in the environment. Here is a toy example:-

# example data and program

set.seed(111); y=round(runif(1000)*30); table(y)

g=rep(c(1:200),each=5); xt=rep(c(1:5),200); table(xt,g)

x1=rnorm(1000); x2=rnorm(1000); x3=rnorm(1000)

data=data.frame(cbind(g,xt,y,x1,x2,x3)); data[1:10,]

# now try to set up the formula

library(brms)

bflog=nlf(asym~x1+(1|g)+lognormal()) + nlf(midy~x2+(1|g)) + nlf(halft~x3+(1|g)+lognormal()) + nlf(asym/(1+exp(midy-xt)/halft)) + set_nl(TRUE)

#> Error in nlf(asym ~ x1 + (1 | g) + lognormal()) + nlf(midy ~ x2 + (1 | :

#> non-numeric argument to binary operator

# alternatively, make asym and halft positive later, by specifying lognormal (or truncated normal) priors

bflog=nlf(asym~x1+(1|g)) + nlf(midy~x2+(1|g)) + nlf(halft~x3+(1|g)) + nlf(asym/(1+exp(midy-xt)/halft)) + set_nl(TRUE)

#> Error in nlf(asym ~ x1 + (1 | g)) + nlf(midy ~ x2 + (1 | g)) :

#> non-numeric argument to binary operator

You cannot mix linear and non-linear formula syntax. That is (1 | g) does not belong inside a nonlinear formula.

1 Like