如何删除带有 NA 和 NA 之后的行?

How do I delete rows with NAs and those that follow the NAs?

我有一些数据,我想在其中删除 NA 以及在 NA 之后按因子级别的数据。

删除 NA 很容易:

df <- data.frame(a=c("A","A","A","B","B","B","C","C","C","D","D","D"), b=c(0,1,0,0,0,0,0,1,0,0,0,1) ,c=c(4,5,3,2,1,5,NA,5,1,6,NA,2))
df
newdf<-df[complete.cases(df),];newdf

最终结果应该删除 C 的所有行和 D 的最后两行。

希望对您有所帮助。

我们可以试试data.table。将'data.frame'转换为'data.table'(setDT(df)),按'a'分组,得到'c'中NA个元素逻辑向量的累加和,判断是否为小于 1 到子集

library(data.table)
setDT(df)[,  .SD[cumsum(is.na(c))<1], by= a]

或者更快的选项 .I 到 return 逻辑向量的行索引和子集行。

setDT(df)[df[, .I[cumsum(is.na(c)) < 1], by = a]$V1]
#   a b c
#1: A 0 4
#2: A 1 5
#3: A 0 3
#4: B 0 2
#5: B 0 1
#6: B 0 5
#7: D 0 6

dplyr 中的类似解决方案是

library(dplyr)
df %>% group_by(a) %>% filter(!is.na(cumsum(c)))

输出:

Source: local data frame [7 x 3]
Groups: a [3]

       a     b     c
  <fctr> <dbl> <dbl>
1      A     0     4
2      A     1     5
3      A     0     3
4      B     0     2
5      B     0     1
6      B     0     5
7      D     0     6

如果我们取变量 C 的累加和,第一个 NA 之后的任何值都将转换为 NA。在组级别执行此操作允许我们删除 NA 行并获得所需的输出。

基本 R 中的经典拆分应用组合:

do.call(rbind,lapply(split(df, df$a),function(x)x[cumsum(is.na(x$c))<1,]))

又来了,不过分几行:

split_df <- split(df, df$a)
apply_df <- lapply(split_df, function(x)x[cumsum(is.na(x$c))<1,])
combine_df <- do.call(rbind, apply_df)

结果:

> do.call(rbind,lapply(split(df, df$a),function(x)x[cumsum(is.na(x$c))<1,]))
#    a b c
#A.1 A 0 4
#A.2 A 1 5
#A.3 A 0 3
#B.4 B 0 2
#B.5 B 0 1
#B.6 B 0 5
#D   D 0 6