【问题标题】:using R to select rows in data set with matching missing observations使用 R 在数据集中选择具有匹配缺失观测值的行
【发布时间】:2012-02-02 10:47:17
【问题描述】:

我已确定如何识别数据集中所有独特的缺失观察模式。现在,我想选择该数据集中具有给定缺失观察模式的所有行。我想迭代地执行此操作,以便如果数据集中有 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 个结果数据集,但我确实将它们与我的真实数据一起保存。

感谢您的任何建议。

马克·米勒

【问题讨论】:

    标签: r


    【解决方案1】:
    # 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,]) )
    }
    

    【讨论】:

      【解决方案2】:

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

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

      is.na(dd)
      

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

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

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

      创建一个类似于您的 zzz 矩阵的矩阵,但您当然可以用“TRUE”代替 NA,用“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 行匹配,其余行相同。

      【讨论】:

      • 谢谢你们俩。这两个答案都给出了我希望的结果并且非常有帮助。马克米勒
      猜你喜欢
      • 2016-07-04
      • 2015-10-29
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      相关资源
      最近更新 更多