2

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'))

1 Answers1

2

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.

Noah
  • 3,437
  • 1
  • 11
  • 27
  • Thanks Noah, I can work with this! See comment below for ideal workflow. Your packages are incredibly useful b.t.w! Thanks for all you do. – Joseph Bulbulia Jul 27 '22 at 22:47
  • Noah, unfortunately, your proposed solution does not work. It will throw an error. The correct solution appears to have been deleted. I will attempt to state it again for those who want a solution for integrating MatchThem with BRMS. – Joseph Bulbulia Jul 29 '22 at 09:04
  • 1
    I made some edits to my answer to isolate and solve the problem. I also made a [bug report](https://github.com/paul-buerkner/brms/issues/1383) to `brms` since I believe my original solution should not throw an error. – Noah Jul 29 '22 at 16:24