基于行内NA的数量的条件行删除

时间:2013-03-03 14:26:22

标签: r list na

我希望根据以下两个条件从我的数据集中删除行:

  1. 如果连续3个单元格为NA
  2. ,则删除行
  3. 如果有四个或更多单元格为NA
  4. 我的示例数据:

    data <- rbind(c(1,1,2,3,4,2,3,2),
                  c(NA,1, NA, 4,1,1,NA,2), 
                  c(1,4,6,7,3,1,2,2), 
                  c(NA,3, NA, 1,NA,2,NA,NA), 
                  c(1,4, NA, NA,NA,4,3,2))
    

    我已经在现有问题中进行了研究,发现na.omitcomplete.cases可以删除NA行,但由于我有条件,进行进一步研究后我发现了以下代码现有问题:

    data[! rowSums(is.na(data)) >4  , ]   
    data[! rowSums(is.na(data)) ==3  , ]
    

    第一行完全填满我的第二个条件。第二行确实删除了包含三个NA的行,但未查找连续行并删除总共3 NA个行的任何行。例如:

    > data
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    [1,]    1    1    2    3    4    2    3    2
    [2,]   NA    1   NA    4    1    1   NA    2
    [3,]    1    4    6    7    3    1    2    2
    [4,]   NA    3   NA    1   NA    2   NA   NA
    [5,]    1    4   NA   NA   NA    4    3    2
    
    > data[! rowSums(is.na(data)) ==3  , ]
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    [1,]    1    1    2    3    4    2    3    2
    [2,]    1    4    6    7    3    1    2    2
    [3,]   NA    3   NA    1   NA    2   NA   NA
    

    我真正想要的是第5行要删除,因为它有三个连续的NA&#39}而不是第二行。

    有人可以建议我如何克服这个问题?

2 个答案:

答案 0 :(得分:6)

两个条件一次:

data[!apply(is.na(data), 1, function(x) 
  {v <- cumsum(x); any(diff(v, 3) == 3) | 4 %in% v}), ]
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# [1,]    1    1    2    3    4    2    3    2
# [2,]   NA    1   NA    4    1    1   NA    2
# [3,]    1    4    6    7    3    1    2    2
如果连续三次any(diff(v, 3) == 3)(因此差异为3),则{p> TRUENA4 %in% v对应第二个条件。

答案 1 :(得分:5)

不是美女,但它会起作用:

rle.na <- apply(is.na(data), 1, function(z){
  tmp <- rle(z)
  tmp$lengths[tmp$values]
})
data[!sapply(rle.na, function(z) any(z == 3)) | rowSums(is.na(data)) > 4, ]