I would like to get custom pairwise contrasts and Holm adjustment for a linear quantile mixed model generated using the lqmm and glht functions, but my attempt generates an error. For comparison, I show that this is possible with a linear mixed model using lmer.
## Load necessary packages
library(lqmm); library(lme4); library(multcomp)
## Orthodont data
data(Orthodont) # head(Orthodont) str(Orthodont)
Orthodont$age = as.factor(Orthodont$age)
# Random intercept model
fit_lmm <- lmer(distance ~ (1 | Subject ) + age, data = Orthodont) # summary(fitOi.lmm)
fit_lqmm <- lqmm(distance ~ age, random = ~ 1, group = Subject,
tau = c(0.1,0.5,0.9), data = Orthodont) # summary(fitOi.lqmm)
### define contrast matrix
contr <- rbind("10 - 8" = c(-1, 1, 0, 0),
"12 - 8" = c(-1, 0, 1, 0),
"12 - 10" = c(0, -1, 1, 0))
contrast_lmm = summary(glht(fit_lmm, linfct = mcp(age = contr), test="holm")) # this works
contrast_lmm
Simultaneous Tests for General Linear Hypotheses
Multiple Comparisons of Means: User-defined Contrasts
Fit: lmer(formula = distance ~ (1 | Subject) + age, data = Orthodont)
Linear Hypotheses:
Estimate Std. Error z value Pr(>|z|)
10 - 8 == 0 0.9815 0.3924 2.501 0.033067 *
12 - 8 == 0 2.4630 0.3924 6.277 < 1e-04 ***
12 - 10 == 0 1.4815 0.3924 3.776 0.000472 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Adjusted p values reported -- single-step method)
The following line of code generates an error.
contrast_lmm = summary(glht(fit_lqmm, linfct = mcp(age = contr), test="holm"))
Error in terms.default(object) : no terms component nor attribute
Error in factor_contrasts(model) :
no ‘model.matrix’ method for ‘model’ found!
EDIT 1
The emmeans package also does not work with lqmm models, and the qdrg function does not work to create a reference grid.
EDIT 2
Here I try out and expand on the suggestion on 6 Apr 2020 by Russ Lenth using the emmeans package.
dummy = 1
fit_lqmm_slopes = as.data.frame(t(c(dummy=dummy, fit_lqmm$theta_x[2:nrow(fit_lqmm$theta_x),"0.5"])))
fit_lqmm_intcpts_df = data.frame(dummy=dummy, intercept = fit_lqmm$y) # head(fit_lqmm_intcpts_df)
fit_lqmm_coef_mat = data.matrix(merge(fit_lqmm_intcpts_df,fit_lqmm_slopes)[,2:(ncol(fit_lqmm_slopes)+1)]) # head(fit_lqmm_coef_mat) # coef(fit_lmm)
fit_lqmm_qdrg = qdrg(formula = ~age, vcov = VarCorr(fit_lqmm)$'0.5', coef = fit_lqmm_coef_mat, df = fit_lqmm$rdf, data = Orthodont)
This gives the error message:
Error in ref_grid(result, ...) :
Non-conformable elements in reference grid.
Probably due to rank deficiency not handled as expected.
I am concerned that the variance-covariance entry (vcov argument) is not specified correctly. So far I can only extract the variance-covariance "matrix" for the random effect using lqmm:VarCorr, which yields a single value for each quantile. I cannot find a way to extract the full variance-covariance matrix from the lqmm object to match the structure of vcov(fit_lmm). I constructed the coefficient data frame to match the structure given by coef(fit_lmm). Should the formula include the random intercept (1 | Subject)?
VarCorr
is definitely the wrong thing to use. That would be estimates of the mixed-effects part of the model. You need the covariance matrix of the fixed effects. As I suggested, that's probably intheta_z
. It may take some doing, as it appeared from the documentation that it saves only the lower (or upper?) triangle of that matrix (e.g., 1+2+3+4=10 elements of a 4x4 matrix) $\endgroup$theta_z
slot is also for the random effects, not the fixed effects. I'll add to my answer. $\endgroup$