使用R选择匹配缺失观察值的数据集中的行

时间:2012-02-02 01:57:55

标签: r

我已经确定了如何识别数据集中所有缺失观察的独特模式。现在我想用给定的缺失观察模式选择该数据集中的所有行。我想迭代地这样做,这样如果数据集中有n个缺失观察模式,我最终会得到n个数据集,每个数据集只包含1个缺失观察模式。

我知道如何做到这一点,但我的方法不是很有效,而且不是一般的。我希望学习一种更有效,更通用的方法,因为我的实际数据集比下面的例子更大,更可变。

这是一个示例数据集和我正在使用的代码。我不打算在矩阵dd中包含用于创建矩阵zzz的代码,但如果有帮助则可以添加该代码。

dd  <- matrix(c( 
            1, 0, 1, 1,
            NA, 1, 1, 0, 
            NA, 0, 0, 0, 
            NA, 1,NA, 1, 
            NA, 1, 1, 1, 
             0, 0, 1, 0, 
            NA, 0, 0, 0, 
             0,NA,NA,NA, 
             1,NA,NA,NA, 
             1, 1, 1, 1, 
            NA, 1, 1, 0), 
nrow=11, byrow=T) 

zzz <- matrix(c(
             1, 1, 1, 1,
            NA, 1, 1, 1, 
            NA, 1,NA, 1, 
             1,NA,NA,NA
), nrow=4, byrow=T) 

for(jj in 1:dim(zzz)[1]) { 
ddd <- 
dd[ 
((dd[, 1]%in%c(0,1) & zzz[jj, 1]%in%c(0,1)) | 
    (is.na(dd[, 1]) & is.na(zzz[jj, 1]))) & 
((dd[, 2]%in%c(0,1) & zzz[jj, 2]%in%c(0,1)) | 
(is.na(dd[, 2]) & is.na(zzz[jj, 2]))) & 
((dd[, 3]%in%c(0,1) & zzz[jj, 3]%in%c(0,1)) | 
(is.na(dd[, 3]) & is.na(zzz[jj, 3]))) & 
((dd[, 4]%in%c(0,1) & zzz[jj, 4]%in%c(0,1)) | 
(is.na(dd[, 4]) & is.na(zzz[jj, 4]))),] 

print(ddd) 
} 

此示例中的4个结果数据集是:

a) 
1    0    1    1 
0    0    1    0 
1    1    1    1 

b) 
NA    1    1    0 
NA    0    0    0 
NA    1    1    1 
NA    0    0    0 
NA    1    1    0 

c) 
NA  1 NA  1 

d) 
0   NA   NA   NA 
1   NA   NA   NA 

是否有更通用,更有效的方法来做同样的事情?在上面的示例中,不会保存4个结果数据集,但我会使用我的实际数据保存它们。

感谢您的任何建议。

马克米勒

2 个答案:

答案 0 :(得分:3)

# Missing value patterns (TRUE=missing, FALSE=present)
patterns <- unique( is.na(dd) )

result <- list()
for( i in seq_len(nrow(patterns))) {
  # Rows with this pattern
  rows <- apply( dd, 1, function(u) all( is.na(u) == patterns[i,] ) )
  result <- append( result, list(dd[rows,]) )
}

答案 1 :(得分:1)

我不完全确定我理解这个问题,但这是一个刺痛......

你要做的第一件事是找出哪些元素是NA,哪些不是。为此,您可以使用is.na()函数。

is.na(dd)

将生成一个与dd相同大小的矩阵,其中包含TRUE,其中值为NA,其他地方为FALSE。

然后,您想在矩阵中找到独特的模式。为此,您需要unique()函数,它接受'margin'参数,允许您只查找矩阵中的唯一行。

zzz <- unique(is.na(dd), margin=1)

创建一个类似于你的zzz矩阵的矩阵,当然,你可以用“TRUE”替换NAs,将“FALSE”替换为1,这样它就会与你的矩阵相同。

然后,您可以从此处转到几个方向,尝试将这些方向分类到不同的数据集中。不幸的是,我认为你在这里需要一个循环。

results <- list()
for (r in 1:nrow(dd)){
  ind <- which(apply (zzz, 1, function(x) {all(x==is.na(dd[r,]))}))
  if (ind %in% names(results)){
    results[[ind]] <- rbind(results[[ind]], dd[r,])
  }
  else{
    results[[ind]] <- dd[r,]
    names(results)[ind] <- ind
  }
}

此时,您有一个列表,其中包含dd的所有行,按照NA的模式排序。您会发现zzz第1行中表示的模式将与结果的第1行匹配,而其余行则相同。