Non-linear hurdle model

I am fitting an IRT-hurdle model in brms. A version without discrimination parameters (=factor loadings) was straightforward to specify. Based on Paul’s brms-IRT paper, I am trying to extend the syntax. The idea is, that both, the hurdle part and the positive part have discrimination parameters:

formula_2pl_2pl <- 
 bf(
   Y        ~ exp(loga)     * eta2,
   hu       ~ exp(logalpha) * eta1,
   shape    ~ 1 + (1|IDitem|item),
   logalpha ~ 1 + (1|IDitem|item),
   loga     ~ 1 + (1|IDitem|item),
   eta1     ~ 1 + (1|IDitem|item) + (1|IDperson|person),
   eta2     ~ 1 + (1|IDitem|item) + (1|IDperson|person),
   nl = TRUE
 )

discriminationHurdle_prior <-
 prior("lkj(1)", class = "cor") +
 prior("normal(0,5)", class = "b", nlpar = "logalpha") +
 prior("normal(0,5)", class = "b", nlpar = "loga") +
 prior("constant(1)", class = "sd", group = "person", nlpar = "eta2") +
 prior("constant(1)", class = "sd", group = "person", nlpar = "eta1")


brm_fit_2pl_2pl <- 
 brm(
   formula_2pl_2pl,
   data = dat,
   family = hurdle_negbinomial,
   prior = discriminationHurdle_prior,
   cores = 2,
   chains = 1,   # for testing 
   iter = 20, # for testing   
)

Calling brm invokes brms:::brmsterms.brmsformula for checking which throws the error:

Error in `brmsterms.brmsformula()`:
! The parameter 'logalpha' is not a valid distributional or non-linear parameter. Did you forget to set 'nl = TRUE'?
Run `rlang::last_trace()` to see where the error occurred.

Investigating a bit with debug(…) I can see that internal processing of the above formula only leads to a non-linear formula for the positive part:

Browse[1]> x$pforms
$mu
mu ~ exp(loga) * eta2
attr(,"nl")
[1] TRUE
attr(,"loop")
[1] TRUE

$hu
hu ~ alpha * eta1

$shape
shape ~ 1 + (1 | IDitem | item)

$logalpha
logalpha ~ 1 + (1 | IDitem | item)

$loga
loga ~ 1 + (1 | IDitem | item)

$eta1
eta1 ~ 1 + (1 | IDitem | item) + (1 | IDperson | person)

$eta2
eta2 ~ 1 + (1 | IDitem | item) + (1 | IDperson | person)

I.e., only mu is non-linear internally, though hu is also supposed to be non-linear. How can I talk brms into doing this?

Here is what I learned: nl = TRUE only makes the main formula non-linear. Wrapping further non-linear formulae in nlf(...) communicates to brms that these are non-linear as well. The following now compiles:

bf(
   Y        ~ exp(loga)     * eta2,
   nlf(hu       ~ exp(logalpha) * eta1),
   shape    ~ 1 + (1|IDitem|item),
   logalpha ~ 1 + (1|IDitem|item),
   loga     ~ 1 + (1|IDitem|item),
   eta1     ~ 1 + (1|IDitem|item) + (1|IDperson|person),
   eta2     ~ 1 + (1|IDitem|item) + (1|IDperson|person),
   nl = TRUE
 )
1 Like

Thanks for reporting back, @Philipp_Doebler, and welcome to the Stan Forums.