Search code examples
rdataframer-micequantile-regression

Is it possible to use lqmm with a mira object?


I am using the package lqmm, to run a linear quantile mixed model on an imputed object of class mira from the package mice. I tried to make a reproducible example:

library(lqmm)
library(mice)
summary(airquality)
imputed<-mice(airquality,m=5)
summary(imputed)
fit1<-lqmm(Ozone~Solar.R+Wind+Temp+Day,random=~1,
           tau=0.5, group= Month, data=airquality,na.action=na.omit)
fit1
summary(fit1)
fit2<-with(imputed, lqmm(Ozone~Solar.R+Wind+Temp+Day,random=~1,
                    tau=0.5, group= Month, na.action=na.omit)) 
"Error in lqmm(Ozone ~ Solar.R + Wind + Temp + Day, random = ~1, tau = 0.5,  : 
  `data' must be a data frame"

Solution

  • Yes, it is possible to get lqmm() to work in mice. Viewing the code for lqmm(), it turns out that it's a picky function. It requires that the data argument is supplied, and although it appears to check if the data exists in another environment, it doesn't seem to work in this context. Fortunately, all we have to do to get this to work is capture the data supplied from mice and give it to lqmm().

    fit2 <- with(imputed, 
                 lqmm(Ozone ~ Solar.R + Wind + Temp + Day,
                      data = data.frame(mget(ls())),
                      random = ~1, tau = 0.5, group = Month, na.action = na.omit)) 
    

    The explanation is that ls() gets the names of the variables available, mget() gets those variables as a list, and data.frame() converts them into a data frame.


    The next problem you're going to find is that mice::pool() requires there to be tidy() and glance() methods to properly pool the multiple imputations. It looks like neither broom nor broom.mixed have those defined for lqmm. I threw together a very quick and dirty implementation, which you could use if you can't find anything else.
    To get pool(fit2) to run you'll need to create the function tidy.lqmm() as below. Then pool() will assume the sample size is infinite and perform the calculations accordingly. You can also create the glance.lqmm() function before running pool(fit2), which will tell pool() the residual degrees of freedom. Afterwards you can use summary(pooled) to find the p-values.

    tidy.lqmm <- function(x, conf.int = FALSE, conf.level = 0.95, ...) {
      broom:::as_tidy_tibble(data.frame(
        estimate = coef(x),
        std.error = sqrt(
          diag(summary(x, covariance = TRUE, 
                       R = 50)$Cov[names(coef(x)),
                                   names(coef(x))]))))
    }
    glance.lqmm <- function(x, ...) {
      broom:::as_glance_tibble(
        logLik = as.numeric(stats::logLik(x)),
        df.residual = summary(x, R = 2)$rdf,
        nobs = stats::nobs(x),
        na_types = "rii")
    }
    

    Note: lqmm uses bootstrapping to estimate the standard error. By default it uses R = 50 bootstrapping replicates, which I've copied in the tidy.lqmm() function. You can change that line to increase the number of replicates if you like.

    WARNING: Use these functions and the results with caution. I know just enough to be dangerous. To me it looks like these functions work to give sensible results, but there are probably intricacies that I'm not aware of. If you can find a more authoritative source for similar functions that work, or someone who is familiar with lqmm or pooling mixed models, I'd trust them more than me.