0
$\begingroup$

I am trying to do multiple imputation on a data set like below. This is a dummy data set. There are no missing values for variables idnum and eye. But specific idnum should have same bmi and gender for both the eyes. The values of cct are different for both eyes of same patient. Can we still use mice package in R for this kind of imputation? Could anyone provide any guidance?

dat <- data.frame(
  idnum = c(101,101,102,102,103,103,104,104,105,105,106,106),
  eye = c("L","R","L","R","L","R","L","R","L","R","L","R"),
  bmi = c(23,NA,26,26,22,NA,18,18,20,20,NA,NA), 
  cct = c(21.3,20.1,18.3,NA,20.1,19,22.4,21,19,NA,18.3,17.8),
  gender = c("male","male","female",NA,"male",NA,"female","female","male","male",NA,NA))

enter image description here

$\endgroup$
1
$\begingroup$

Yes, the mice package can make imputations for data like this.

In the example code below, I first copy any partially observed data into the rest of that idnum. Next I transform the data from "long" into "wide" format. There will be 1 row for each idnum. The idnum, bmi, and gender variables will stay as they are, but the eye and cct variables will be combined into cct_L and cct_R. After that we can run the mice function as usual, although in this example data we'll need to tweak which variables are used as predictors of the others, otherwise the models will be over-specified.

After the imputations are created you can transform back into the longer format with pivot_longer. I find it's easiest to do that inside the with call that fits the analysis to each imputed dataset.

library(tidyverse)
library(mice)
dat <- data.frame(
  idnum = c(101,101,102,102,103,103,104,104,105,105,106,106),
  eye = c("L","R","L","R","L","R","L","R","L","R","L","R"),
  bmi = c(23,NA,26,26,22,NA,18,18,20,20,NA,NA), 
  cct = c(21.3,20.1,18.3,NA,20.1,19,22.4,21,19,NA,18.3,17.8),
  gender = c("male","male","female",NA,"male",NA,"female","female","male","male",NA,NA))
dat$gender <- factor(dat$gender)
dat$eye <- factor(dat$eye)

# Match all observed data
check_na <- function(x) {
  stopifnot(length(x) == 2)
  if(!is.na(x[1]) & !is.na(x[2])) {
    if(x[1] == x[2]) {
      return(x)
    } else {
      stop("two values for the same idnum don't match")
    }
  }
  if(is.na(x[1]) & is.na(x[2])) {
    return(x)
  }
  if(!is.na(x[1]) & is.na(x[2])) {
    return(c(x[1],x[1]))
  }
  if(is.na(x[1]) & !is.na(x[2])) {
    return(c(x[2],x[2]))
  }
  stop("should never reach here")
}
dat_fixed <- dat
for(i in unique(dat$idnum)) {
  dat_fixed[dat_fixed$idnum == i,]$bmi <- 
check_na(dat_fixed[dat_fixed$idnum == i,]$bmi)
  dat_fixed[dat_fixed$idnum == i,]$gender <- 
check_na(dat_fixed[dat_fixed$idnum == i,]$gender)
}

# Transform data into wide format
dat_wide <- 
  pivot_wider(dat_fixed,
              id_cols = c("idnum","bmi","gender"),
              names_from = "eye",
              names_prefix = "cct_",
              values_from = "cct")
dat_wide
#> # A tibble: 6 x 5
#>   idnum   bmi gender cct_L cct_R
#>   <dbl> <dbl> <fct>  <dbl> <dbl>
#> 1   101    23 male    21.3  20.1
#> 2   102    26 female  18.3  NA  
#> 3   103    22 male    20.1  19  
#> 4   104    18 female  22.4  21  
#> 5   105    20 male    19    NA  
#> 6   106    NA <NA>    18.3  17.8

# Specify which variables to use for imputations
pred <- quickpred(dat_wide)
pred[,] <- 0
pred["cct_R",c("bmi","cct_L")] <- 1
pred[c("bmi","gender"),c("bmi","gender")] <- 1
diag(pred) <- 0

# Make imputations
imps <- mice(dat_wide,
             m = 5,
             seed = 123,
             predictorMatrix = pred,
             printFlag = FALSE)

# View one of the imputed datasets
complete(imps, action = 1)
#>   idnum bmi gender cct_L cct_R
#> 1   101  23   male  21.3  20.1
#> 2   102  26 female  18.3  20.1
#> 3   103  22   male  20.1  19.0
#> 4   104  18 female  22.4  21.0
#> 5   105  20   male  19.0  20.1
#> 6   106  23 female  18.3  17.8
$\endgroup$
2
  • $\begingroup$ Thank you very much David. I tried your codes and transformed that back in to long format and fitted the model. It is working well. I have one more question. If I use the mice function in the following way it doesn't count the last variable cct_R for imputation. imps<-mice(dat_wide, m=5,maxit=50,method = c('','pmm','polyreg','pmm','pmm'), seed = 500). Here I am assigning the method of imputation for each column. As we don't do the imputation on IDNUM, I kept that as empty. $\endgroup$
    – ACHD
    May 27 '21 at 2:27
  • $\begingroup$ @ACHD, The code I wrote didn't use cct_R as a predictor for imputations, you'll need to change pred to have a specification that makes sense for your purpose. But when I run the code in your comment on the sample data I get an error because polyreg is not appropriate for imputing a binary variable. If I change it to logreg the code runs (aside from warnings about choice of predictors). If neither of those are your problem could you please clarify where your trouble is? $\endgroup$ May 27 '21 at 18:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.