通过用 R 中所有可能值的集合替换缺失值来扩展 data.frame

Expanding a data.frame by replacing missing values with set of all possible values in R

我想通过用所有可能行的集合替换每个不完整的行来扩展我的数据集。有人对执行此操作的有效方法有任何建议吗?

例如,假设 X 和 Z 都可以取值 0 或 1。

输入:

   id y  x  z
 1  1 0  0 NA
 2  2 1 NA  0
 3  3 0  1  1
 4  4 1 NA NA

输出:

  id y x z
1  1 0 0 0
2  1 0 0 1
3  2 1 0 0
4  2 1 1 0
5  3 0 1 1
6  4 1 0 0
7  4 1 0 1
8  4 1 1 0
9  4 1 1 1

目前我只是逐行处理原始数据集:

for(i in 1:N){

if(is.na(temp.dat$x[i]) & !is.na(temp.dat$z[i])){
    augment <- matrix(rep(temp.dat[i,],2),ncol=ncol(temp.dat),byrow=TRUE)
    augment[,3] <- c(0,1)
}else
if(!is.na(temp.dat$x[i]) & is.na(temp.dat$z[i])){
    augment <- matrix(rep(temp.dat[i,],2),ncol=ncol(temp.dat),byrow=TRUE)
    augment[,4] <- c(0,1)
}else{
if(is.na(temp.dat$x[i]) & is.na(temp.dat$z[i])){
    augment <- matrix(rep(temp.dat[i,],4),ncol=ncol(temp.dat),byrow=TRUE)
    augment[,3] <- c(0,0,1,1)
    augment[,4] <- c(0,1,0,1)
}
}

你可以试试

  1. 在每行中创建一个“NA”计数的“索引”(rowSums(is.na(...))

  2. 使用“index”扩展原始数据集的行数(df[rep(1:nrow...)

  3. 循环(sapply)“indx”并将其用作rep中的“times”参数,然后对值[=17]执行expand.grid =] 创建“lst”

  4. split 扩展数据集“df1”,按“id”

  5. 使用Map将“lst2”中相应的“NA”值更改为“lst”中的值

  6. rbind 列表元素

    indx <- rowSums(is.na(df[-1]))
    df1 <- df[rep(1:nrow(df), 2^indx),]
    lst <- sapply(indx, function(x) expand.grid(rep(list(0:1), x)))
    lst2 <- split(df1, df1$id)
    res <- do.call(rbind,Map(function(x,y) {x[is.na(x)] <- as.matrix(y);x},
                              lst2, lst))
    row.names(res) <- NULL
    res
    #  id y x z
    #1  1 0 0 0
    #2  1 0 0 1
    #3  2 1 0 0
    #4  2 1 1 0
    #5  3 0 1 1
    #6  4 1 0 0
    #7  4 1 1 0
    #8  4 1 0 1
    #9  4 1 1 1
    

数据

df <- structure(list(id = 1:4, y = c(0L, 1L, 0L, 1L), x = c(0L, NA, 
1L, NA), z = c(NA, 0L, 1L, NA)), .Names = c("id", "y", "x", "z"
), class = "data.frame", row.names = c("1", "2", "3", "4"))