同一列中连续出现的NA值

6

我希望删除一个列中有超过3个连续的NA的行。

      [,1] [,2] 
[1,]    1    1   
[2,]   NA    1   
[3,]    2    4   
[4,]   NA    3   
[6,]    1    4   
[7,]   NA    8
[8,]   NA    5
[9,]   NA    6

所以我会有这些数据

      [,1] [,2] 
[1,]    1    1   
[2,]   NA    1   
[3,]    2    4   
[4,]   NA    3   
[6,]    1    4 

我做了一些研究并尝试了这段代码

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

但我认为这仅适用于连续的NA


2
在上方搜索[r] rle,因为已经有很多关于强大的rle()函数的答案,这也将对您有所帮助。 - Dirk Eddelbuettel
2
这个问题应该会有所帮助,但标题可能会误导。 - Justin
3个回答

13

如前所述,rle 是一个不错的起点:

is.na.rle <- rle(is.na(data[, 1]))

由于只有三个或三个以上的NAs才是“坏”的,因此我们可以重新编写这些值:

is.na.rle$values <- is.na.rle$values & is.na.rle$lengths >= 3

最后,使用inverse.rle构建索引向量以进行过滤:

data[!inverse.rle(is.na.rle), ]

3

你可以使用rle,或者你可以这样做:

library(data.table)

d = data.table(a = c(1,NA,2,NA,3,4,NA,NA,NA), b = c(1:9))

d[d[, if(.N > 3) {.I[1]} else {.I}, by = cumsum(!is.na(a))]$V1]
#    a b
#1:  1 1
#2: NA 2
#3:  2 3
#4: NA 4
#5:  3 5
#6:  4 6

运行 d [,cumsum(!is.na(a))] 可以看到为什么这样做。此外,我可以使用.SD 而不是 .I 来获得更清晰的代码,但我选择效率而不是简洁。

2
如@DirkEddelbuettel建议的那样,rle()函数会有所帮助。您可以创建自己的函数来识别具有3个或更多连续NA值的向量的元素。
consecna <- function(x, n=3) {
    # function to identify elements with n or more consecutive NA values
    y <- rle(is.na(x))
    y$values <- y$lengths > (n - 0.5) & y$values
    inverse.rle(y)
    }

然后你可以将此函数应用于矩阵的每一列。
# example matrix of data
m <- matrix(c(1, NA, 2, NA, 1, NA, NA, NA, 1, 1, 4, 3, 4, 8, 5, 6), ncol=2)

# index matrix identifying elements with 3 or more consecutive NA values
mindex <- apply(m, 2, consecna)

然后使用创建的索引矩阵来消除所有已识别的行。
# removal of all the identified rows
m2 <- m[!apply(mindex, 1, any), ]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接