Dichotomous and polytomous items in a single model via differing threshold number

Dear readers,
I want to evaluate a bunch of dichotomous and some polytomous items in a single model. Therefore I intend to model them via cumulative family. My idea is to set the number of thresholds for the dichotomous items thres(1) and set the number of thresholds for the polytomous items as well. The number of thresholds for the polytmous items is heterogenous as well.

Here I assume that the dichotomous model is nested in the cumulative model whith thresholds = 1 in the model generated by brm(). Question 1: Is this correct?

I have some problems to understand the help in the brms documentation. There I found the term thres(6, gr = item) and the hint, that the number of the threshold can be added to the dataset. I tried some formulas and my most recent (similar to the formula in Bürkner, 2019: https://arxiv.org/pdf/1905.09501.pdf) was:

formula_dekl_fachdidaktisches_Wissen_1D_1pl_poly <- bf(
 response | thres(poly, gr = item) ~ 1 + (1 | ID),
 family = brmsfamily("cumulative", link = "logit")

where I assume poly to be the column with threshold numbers in the data set (currently poly is 1 or 2 for any item). This way I got population effect intercepots for all items which are quite comparable to these from MML. But instead of getting one single theta for every pupli I get a theta value for each item now.

Question 2: Is there a way to get only a single (combined?) theta for any pupil?

Question 3: Or am I on a wrong way and there is better method to combine dicotomous and polytomous models? In the next step I want to add item discrimination parameters.

  • Operating System: Win 10x64 1909
  • brms Version: 2.13.5

Sincerely, Simon

May I help you with any additional information to help me with my questions?


as far as I know brms does not handle different numbers of thresholds (i.e. you use the same latent variable for outcome variables with different number of categories) out of the box.
[maybe @paul.buerkner can verify that].

It is possible to “hack” brms to do this by starting with brms-generated Stan code and modifying it.

For a long time, brms did not support varying number of thresholds but it now does. See resp_thres for documentation. You can apply it via y | thres(...) ~ ...

1 Like

Yeah. I found the thres(...) option. But I wasn’t able to get the expected behavior out of it.

First I tried response | thres(poly, gr = f_poly) ~ 1 + (1 | item) + (1 | ID) with poly = {1,2} stating and f_poly = {dich, tri}. This returned three item threshold for any item and three theta values for any person.

Later I came up with response | thres(poly, gr = item) ~ 1 + (1 | ID) which gave me one (population) intercept for any dichotomous item and two for the polytomous (what I expected) but I got a theta value for each item (group) but I expect a singular theta for any person.

If I try response | thres(poly, gr = single_group) ~ 1 + (1 | item) + (1 | ID) whith single_group = factor(1) (any item has the same group) I get the error “Number of thresholds should be unique for each group.”.

And if I try response | thres(poly) ~ ... or response | thres(poly, gr = 1) ~ ... I get the error “Number of thresholds needs to be a single value.”

So my question is how I can specify the formula so I get a single theta for any person but items can differ in their threshold numbers. Is there a way @paul.buerkner ?

Please provide the complete model code plus the corresponding summary output of those models whose results don’t match your expectations.

formula_dekl_fachdidaktisches_Wissen_1D_1pl_poly_thres2b <- bf(
  response | thres(poly, gr = item) ~ 1 + (1 | ID),
  family = brmsfamily("cumulative", link = "logit")

prior_dekl_fachdidaktisches_Wissen_1D_1pl_poly_thres2b <- ...

fit_dekl_fachdidaktisches_Wissen_1D_1pl_poly_tres2b <- brm(
  formula = formula_dekl_fachdidaktisches_Wissen_1D_1pl_poly_thres2b,
  data = daten_MC_und_MAT_id_long,
  cores = 4, iter = 3000, warmup = 2000, control = list(adapt_delta = 0.90),
  file = "models/fit_dekl_fachdidaktisches_Wissen_1D_1pl_poly_tres2b"

Via coef(fit_dekl_fachdidaktisches_Wissen_1D_1pl_poly_tres2b)$ID I get a est. value for any person for every single item. I exported them in a datafile to have an overview:

When I run a GPCM in mirt or TAM I get a single value for every person not for every person * item.

I see. You should use ranef not coef to obtain only the “random effects” without the intercepts/thresholds added to it.