Can you fit the zero-inflated component of a model to a nonlinear expression in brms?

I am running a model and would like to fit the zero-inflated component of a ZIP model to a non-linear expression.

The problem is illustrated in the following toy example:

train <- data.frame(fread("path/to/data/train.csv"))

counts_formula <- counts ~ L + (c - MaxT) * step(MaxT - c)
zi_formula <- zi ~ K + (d - precip) * step(precip - d)
coef_formula <- L + K + c + d ~ 1

brms_formula <- bf(counts_formula,
                   zi_formula,
                   coef_formula,
                   nl = TRUE)

priors <- c(prior(normal(-10,10), nlpar = "L"),
            prior(normal(0,10), nlpar = "K"),
            prior(uniform(0.01, 1), nlpar = "c", lb = 0.01, ub = 1),
            prior(uniform(0.01, 1), nlpar = "d", lb = 0.01, ub = 1))

fit <- brm(brms_formula,
           data = train,
           prior = priors,
           family = zero_inflated_poisson(),
           warmup = 1000, iter = 4000,
           chains = 1, cores = 1,
           control = list(max_treedepth = 10, adapt_delta = 0.9))

This returns the error message:

Error: The parameter 'K' is not a valid distributional or non-linear parameter. Did you forget to set 'nl = TRUE'?
Traceback:

1. brm(brms_formula, data = train, prior = priors, family = zero_inflated_poisson(), 
 .     warmup = 50, iter = 200, chains = 1, cores = 1, control = list(max_treedepth = 10, 
 .         adapt_delta = 0.9))
2. brmsterms(formula)
3. brmsterms.brmsformula(formula)
4. stop2("The parameter '", unused_nlpars[1], "' is not a ", "valid distributional or non-linear parameter. ", 
 .     "Did you forget to set 'nl = TRUE'?")
5. stop(..., call. = FALSE)

The model runs perfectly well if I set the zero-inflation formula to zi ~ 1, but does not work for zi ~ K with the appropriate priors specified.

OS: Linux
brms version: 2.18.0

1 Like

wrap the formula for zi inside nlf(). this should do the trick.

2 Likes

Thanks - and love the package.

Hello, I met the same error, and my code like this:
formula ← bf(
reward ~ V,
V ~ V_prev + alpha * (reward_prev - V_prev) ,
nl = TRUE
) + nlf(
alpha ~ 1,
cmc = FALSE
)

fit ← brm(
formula,
data = data,
family = gaussian(),
prior = c(
prior(normal(0, 1), class = “b”, nlpar = “alpha”),
prior(normal(0, 1), class = “sigma”)
),
control = list(adapt_delta = 0.95)
)
I use nlf, but the error still there: The parameter ‘alpha’ is not a valid distributional or non-linear parameter. Did you forget to set ‘nl = TRUE’?
May I ask, what do you mean by “wrap the formula for zi inside nlf()”?

nl = TRUE only applies to the main formula. If other formulas should also be interpreted as non-linear, you need to wrap them in nlf(). For example, in your case this would mean something like:

formula ← bf(
  reward ~ V,
  nlf(V ~ V_prev + alpha * (reward_prev - V_prev)),
  alpha ~ 1,
  nl = TRUE
)

Thank you so much, it works!