-
Notifications
You must be signed in to change notification settings - Fork 110
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditional imputation: Two solutions #258
Comments
Thanks. Conditional imputation is recurring issue (#43, #125, #152, #153, #193) that has no elegant solution in library(mice, warn.conflicts = FALSE)
data <- data.frame(
age = c(60, 54, 82, NA, 34, 58, 60, 58, 76, 40),
fall = c(0, NA, 1, 0, 1, NA, 1, 1, 0, 1),
aid = factor(c("-", NA, "Yes", "-", "No", NA, "Yes", NA, NA, "No"))
)
pred <- make.predictorMatrix(data)
pred["fall", "aid"] <- 0
pred["age", "aid"] <- 0
post <- make.post(data)
post["aid"] <- paste(sep = "; ",
"fall <- data$fall[!r[,j]] == 1",
"idx <- data$fall == 1",
"imp[[j]][!fall, i] <- levels(data$aid)[1]",
"imp[[j]][fall, i] <- mice.impute.pmm(y = data$aid[idx], ry = r[idx, j], x = model.matrix(aid ~ 0 + age, data[idx, , drop = FALSE]))")
imp <- mice(data, m = 10, pred = pred, post = post, print = FALSE, seed = 1) > data
age fall aid
1 60 0 -
2 54 NA <NA>
3 82 1 Yes
4 NA 0 -
5 34 1 No
6 58 NA <NA>
7 60 1 Yes
8 58 1 <NA>
9 76 0 <NA>
10 40 1 No There are several features that need commenting:
> complete(imp)
age fall aid
1 60 0 -
2 54 0 -
3 82 1 Yes
4 34 0 -
5 34 1 No
6 58 1 Yes
7 60 1 Yes
8 58 1 Yes
9 76 0 -
10 40 1 No
> imp$imp
$age
1 2 3 4 5 6 7 8 9 10
4 34 76 54 76 60 58 60 60 82 82
$fall
1 2 3 4 5 6 7 8 9 10
2 0 1 1 1 1 1 1 1 0 1
6 1 1 0 1 1 1 0 1 1 1
$aid
1 2 3 4 5 6 7 8 9 10
2 - No No No Yes Yes Yes No - No
6 Yes No - Yes No Yes - Yes Yes No
8 Yes Yes Yes Yes No Yes No Yes Yes Yes
9 - - - - - - - - - -
I admit the procedure given above is somewhat complicated, but it does the job, and can be generalised to more difficult problems, for example, to three or more groups and for blocks of variables. Watch out for the case where one of the groups can become empty. An alternative is to write your own Hope this is useful. |
And here's a solution based on a custom imputation function. library(mice, warn.conflicts = FALSE)
data <- data.frame(
age = c(60, 54, 82, NA, 34, 58, 60, 58, 76, 40),
fall = c(0, NA, 1, 0, 1, NA, 1, 1, 0, 1),
aid = factor(c("-", NA, "Yes", "-", "No", NA, "Yes", NA, NA, "No"))
)
pred <- make.predictorMatrix(data)
pred["fall", "aid"] <- 0
pred["age", "aid"] <- 0
meth <- make.method(data)
meth$aid <- "aid"
mice.impute.aid <- function(y, ry, x, wy = NULL, ...) {
if (is.null(wy)) wy <- !ry
fall <- x[, "fall"][!ry] == 1
idx <- x[, "fall"] == 1
vec <- rep(NA, sum(wy))
vec[!fall] <- 1
vec[fall] <- as.integer(mice.impute.pmm(y[idx], ry = ry[idx], x = x[idx, "age", drop = FALSE], ...))
levels(y)[vec]
}
imp <- mice(data, m = 10, maxit = 5, pred = pred, meth = meth, print = FALSE, seed = 1) > imp$imp
$age
1 2 3 4 5 6 7 8 9 10
4 34 60 58 40 82 34 76 58 34 58
$fall
1 2 3 4 5 6 7 8 9 10
2 0 0 0 1 1 1 0 1 0 1
6 1 1 1 1 1 1 1 1 1 0
$aid
1 2 3 4 5 6 7 8 9 10
2 - - - Yes No No - No - Yes
6 Yes Yes Yes Yes Yes Yes Yes Yes No -
8 Yes No No Yes No No No Yes No Yes
9 - - - - - - - - - - |
Dear Stef, Thank you for your help. Your 'post' solution works for numeric variables to predict aid, but not for factors. Please see what happens when I introduce a factor as a predictor in your code: data <- data.frame(
age = c(60, 54, 82, NA, 34, 58, 60, 58, 76, 40),
fall = c(0, NA, 1, 0, 1, NA, 1, 1, 0, 1),
aid = factor(c("-", NA, "Yes", "-", "No", NA, "Yes", NA, NA, "No")),
sex = factor(c("M", NA, "F", "F", "M", NA, "M", "F", "F", "M"))
)
pred <- make.predictorMatrix(data)
pred["fall", "aid"] <- 0
pred["age", "aid"] <- 0
pred["sex", "aid"] <- 0
post <- make.post(data)
post["aid"] <- paste(sep = "; ",
"fall <- data$fall[!r[,j]] == 1",
"idx <- data$fall == 1",
"imp[[j]][!fall, i] <- levels(data$aid)[1]",
"imp[[j]][fall, i] <- mice.impute.pmm(y = data$aid[idx], ry = r[idx, j],
x = model.matrix(aid ~ 0 + age + sex , data[idx, , drop = FALSE]))")
imp <- mice(data, m = 10, pred = pred, post = post, seed = 1)`
>imp <- mice(data, m = 10, pred = pred, post = post, seed = 1)
iter imp variable
1 1 age fall aid
Error in get("printFlag", parent.frame(search.parents("printFlag"))) :
object 'printFlag' not found
``` |
The devil is in the details. Nothing is wrong with your code. Apparently, the introduction of |
Solved in |
Dear Stef, |
Thank you Stef, but I couldn´t. This is what I got (R 4.0.2, Windows 10):
1: All Enter one or more numbers, or an empty line to skip updates:1 There are binary versions available but the source versions are later: installing the source packages ‘vctrs’, ‘backports’ trying URL 'https://ftp.cixug.es/CRAN/src/contrib/vctrs_0.3.4.tar.gz' trying URL 'https://ftp.cixug.es/CRAN/src/contrib/backports_1.1.9.tar.gz'
|
Not related to |
Dear all, I'm trying to solve a similar problem, however in my example aid would have an additional level, leaving 3 options when fall == 1 and I would like to use "polyreg" as a method for the imputation (as this is used for other multicategorical variables in my imputation model), I keep getting errors when adapting following code to polyreg , can someone help? post["aid"] <- paste(sep = "; ", Thank you! |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Dear fellows,
I'm using your excellent package MICE.
I have two variables that I need to impute together:
caidas
is the number of falls (numeric), andcq18b
is a variable of the care received by the person who fell; it is a factor with levelsWhen imputing
caidas
, I want that ifcaidas==0
,cq18b==1
and ifcaidas>0
cq18b
gets either an imputed 2 or 3.This fragment of code limits the second imputation to 3, but I'd like that it imputes 2 or 3, depending on other predictors.
Any idea?
Thank you for your time and attention,
Ángel
The text was updated successfully, but these errors were encountered: