Search code examples
r-micepropensity-score-matchingbrms

Is there a method for converting a winmids object to a mids object?


Suppose I create 10 multiply-imputed datasets and use the (wonderful) MatchThem package in R to create weights for my exposure variable. The MatchThem package takes a mids object and converts it to an object of the class winmids.

My desired output is a mids object - but with weights. I hope to pass this mids object to BRMS as follows:

library(brms)
m0 <- brm_multiple(Y|weights(weights) ~ A, data = mids_data)

Open to suggestions.

EDIT: Noah's solution below will unfortunately not work.

The package's first author, Farhad Pishgar, sent me the following elegant solution. It will create a mids object from a winmidsobject. Thank you Farhad!

library(mice)
library(MatchThem)

#"weighted.dataset" is our .wimids object

#Extracting the original dataset with missing value
maindataset <- complete(weighted.datasets, action = 0)

#Some spit-and-polish
maindataset <- data.frame(.imp = 0, .id = seq_len(nrow(maindataset)), maindataset)

#Extracting imputed-weighted datasets in the long format
alldataset  <- complete(weighted.datasets, action = "long")

#Binding them together
alldataset  <- rbind(maindataset, alldataset)

#Converting to .mids
newmids <- as.mids(alldataset)

Additionally, for BRMS, I worked out this solution which instead creates a list of dataframes. It will work in fewer steps.

library("mice")
library("dplyr")
library("MatchThem")
library("brms") # for bayesian estimation.  

# Note, I realise that my approach here is not fully Bayesian, but that is a good thing!  I need to ensure balance in the exposure.  

# impute missing data 
data("nhanes2")
imp <- mice(nhanes2, printFlag = FALSE, seed = 0, m = 10)


# MathThem.  This is just a fast method
w_imp <- weightthem(hyp ~  chl + age, data = imp,
                     approach = "within",
                     estimand = "ATE",
                     method = "ps")

# get individual data frames with weights
out <- complete(w_imp, action ="long", include = FALSE, mild = TRUE)

# assemble individual data frames into a list 
m <- 10
listdat<- list()
for (i in 1:m) {
  listdat[[i]] <- as.data.frame(out[[i]])
}

# pass the list to brms, and it runs as it should!

fit_1 <- brm_multiple(bmi|weights(weights) ~ age + hyp + chl,
                          data = listdat,
                          backend = "cmdstanr",
                          family = "gaussian",
                          set_prior('normal(0, 1)',
                                    class = 'b'))

Solution

  • brm_multiple() can take in a list of data frames for its data argument. You can produce this from the wimids object using complete(). The output of complete() with action = "all" is a mild object, which is a list of data frames, but this is not recognized by brm_multiple() as such. So, you can just convert it to a list. This should look like the following:

    df_list <- complete(mids_data, "all")
    class(df_list) <- "list"
    
    m0 <- brm_multiple(Y|weights(weights) ~ A, data = df_list)
    

    Using complete() automatically adds a weights column to the resulting imputed data frames.