Brms: Plotting three-way interactions with ordinal regression

  • Operating system: Ubuntu 18.04.5 LTS
  • brms version: 2.13.5

I have run an ordinal regression using brms and now am trying to plot the effect of three categorical predictors (Morphology, Cluster2, CountryExperiment) on the response variable (a Likert scale with 7 points). Following the information on the link to conditional_effects, I used the following code:

#model
fit_sc1 <- brm(
  formula = response ~ 1 + Cluster2*Morphology*CountryExperiment  + (1|id) + (1|UnaccentedWord),
  data = datafile.for.model,
  family = cumulative("probit")
)
#plot
conditions <- make_conditions(fit_sc1, "Morphology")
conditional_effects(fit_sc1, "Cluster2:CountryExperiment", conditions = conditions, categorical=TRUE)

But I get the following warning:

Error: No valid effects detected.
In addition: Warning message:
Interactions cannot be plotted directly if 'categorical' is TRUE. Please use argument 'conditions' instead.

I am not sure to understand the message here because I have used the ‘conditions’ argument. Note that everything works fine if I remove categorical=TRUE from the code above: the plot shows the three predictors in facets. But then the predictions are treated as continuous variables (instead of ordinal) on the plot, and this is likely invalid for ordinal families.

Has anyone managed to get around this issue? Thanks!

1 Like

I managed to get what I want using the ordinal regression’s posterior samples to reconstruct the response’s probabilities for all cells in the factorial design. I used Equation (5) p 79 in Buerkner & Vuorre’s paper to find the probability of each of my 7 responses (along a 7-point Likert scale) for each of the 12 conditions (all combinations of my three variables). Equation (5) defines the probability P(Response=k) of each response category k as a function of (i) the 6 thresholds that split the underlying continuous scale, (ii) the predictor variables, and (iii) the corresponding regression coefficients. It was tedious but it works… It would be nice to develop a function that does that automatically.

1 Like

I know that the original poster found a solution that works for him, but can anyone answer the original question? I am trying to plot a two-way interaction and am having the same problem. Other than using family = cratio(), my model is very similar to the one above. I get the same message when attempting to use the make_conditions() function with the categorical = TRUE argument.

I am using Windows 10, R 3.6.1 (because I still have to), and brms version 2.12.0.

Thank you.

In case anyone is interested, following is an example showing how to create an interaction plot (two-way in this case) using the conditional_effects() function.

For the model

mod ← brm(resp ~ var_1 + var_2 * var_3, data = dat)

To plot the interaction between var_2 and var_3, you need a data frame that provides levels of interest for the variables involved in the interaction and holds levels for other variables constant.

conditions ← data.frame(var_1 = ‘level_a’, var_2 = c(‘level_a’, ‘level_b’), var_3 = c(‘level_a’, ‘level_b’))

These conditions can then be used in the conditional_effects furnction. The effects argument should be set to the variable you want on the x-axis in the plot. In this case, we put var_2 on the x-axis.

conditional_effects(mod, effect = ‘var_2’, conditions = conditions)

When doing this, the facet labels will be numeric instead of the values of the second variable in the interaction (var_3 in this case). To have the values of facet variable in the facet labels, do the following

mod_plot ← conditional_effects(mod, effect = ‘var_2’, conditions = conditions)

plot(mod_plot, plot = FALSE)[[1]] +
facet_wrap(‘var_3’)

Looking at str(mod_plot) will help show why this works. The conditional_effects function facets on cats__ when plotted. You can facet on other columns in the object returned by conditional_effects instead.

For a three-way interaction, include multiple levels for a third variable in the conditions data frame above. Then use facet_grid instead of facet_wrap.

I had a similar problem I wanted to graph the interaction between An and LEH_GOS in this regression

rb29 <- brm(Age_p ~ 1 + An + LEH_GOS + An*LEH_GOS, data = Apfo, family=sratio("logit"), cores = 6, inits = 0)

What work for me was to play directly in the dataframe create by conditionnal_effect.

amv2 <- conditional_effects(rb29, categorical = TRUE, conditions =  data.frame( An = c(1976:2019))) 

  amv2[["LEH_GOS:cats__"]]$cond__ <- amv2[["LEH_GOS:cats__"]]$LEH_GOS

amv2[["LEH_GOS:cats__"]]$effect1__ <-amv2[["LEH_GOS:cats__"]]$An

amv2[["LEH_GOS:cats__"]]$effect2__ <- revalue(amv2[["LEH_GOS:cats__"]]$effect2__, c("1"="3", "2"="4","3"="5","4"="5+"))

amv2[["An:cats__"]] <- NULL
   
 amv2

Hi, I’m trying to use your code to plot the conditional effects for three-way interactions. However, using the data.frame function to filter out some levels only work for one variable in the list. For all other variables all levels are still visible. Could you write some example lines of code to reproduce it? It would be very helpful!

Lines not working (it ignores INF and only filters correctly CONDITION, while PROFICIENCY already has 2 levels):

conditions ← data.frame(condition = c(“GN”,“NG”), inf=c(“Syll1”, “Syll3”), proficiency = c(“Beginner”, “Avanced”))

plot<-conditional_effects(m_sync_GL2_p, “proficiency:inf”, conditions = conditions)
plot(plot, plot = FALSE)[[1]] +
facet_wrap(“condition”)