Bypassing the checks on the response when defining a custom family

I am fitting a negative binomial model with trials, using a custom family; closely following the vignette for custom families (https://cran.r-project.org/web/packages/brms/vignettes/brms_customfamilies.html), but I am wanting to pass the number of trials in to the model formula (my reason for this is so that I can change the number of trials when I use the model to predict on new data).

The problem I am having is that the negative binomial allows for a number to be drawn that is higher than the number of trials, and so the model is failing with the error Error: Number of trials is smaller than the number of events. (possibly at this line https://github.com/paul-buerkner/brms/blob/242843d3de39b4311c241c00cb90fff74542ff5d/R/data-predictor.R#L870)

Is there a way to disable this checking, either when defining the custom family, or through setting the check_response flag to False ?

# Minimal example (run on BRMS 2.6.3, Ubuntu 18.04)
library(brms)                                                                 
                                                                              
data <- data.frame(trials=rep(5, 100),                                        
    count=rnbinom(100, size=5*2, prob=0.4))                                   
                                                                              
neg_binomial_2_trials <- custom_family(                                       
    "neg_binomial_2_trials",                                                  
    dpars = c("mu", "phi"),                                                   
    links = c("log", "identity"),                                             
    lb = c(0, 0),                                                             
    type = "int",                                                             
    vars = "trials[n]"                                                        
)                                                                             
                                                                              
stan_funs <- "                                                                
    real neg_binomial_2_trials_lpmf(int y, real mu, real phi, int T) {        
        return neg_binomial_2_lpmf(y | mu * T, phi * T);                      
    }                                                                         
"                                                                             
                                                                              
stanvars <- stanvar(scode = stan_funs, block = "functions")                   
                                                                              
model <- brm(count | trials(trials) ~ 1,                                      
    data=data,                                                                
    family=neg_binomial_2_trials,                                             
    stanvars=stanvars)                                                        

Avoding checks always requires special case coding and I want to avoid that whenver possible.

For your case, I would recommend not using trials(), but rather
stanvars(..., block = "data") to pass unchecked data to Stan.

… I am applying my fitted model to newdata, i.e., predict(model, newdata=newdata), and I couldn’t figure out how to get the updated trials through to the custom predict function. When I copied the example in the vignette, using the stanvars approach, the trials didn’t update from the newdata. This caused me some puzzling, as the predictions ran, but I ended up mixing trials from the training data with newdata being parsed to the predict function. So, I decided I preferred the explicit approach of including the trials in the formula directly, in the usual way.

One way to solve it would be for the particular check (that Y < trials) to only be applied to the binomial distribution, so it is effectively switched off for custom distributions.

You can use the new_objects argument for this purpose.

Let me think of how to handle the check in trials() going forward.

1 Like

Thanks! I am happily diving in over my depth! But in the mean time i have forked the code and switched off the check, and it is all working well :)

That’s indeed a solution as well ;-)

I gave it another look and actually found a function of mine able to differentiate between “natural” trial families like binomial and custom families. In the dev version of brms from github, trials should no longer be checked when used with custom families.

1 Like

Awesome!