我有一些数据,我希望通过因子级别删除NA和NAs之后的数据。
删除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.
希望你能提供帮助。
答案 0 :(得分:4)
我们可以尝试使用data.table。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df)
),按&#39; a&#39;,得到&#39; c&#39;中的NA元素的逻辑向量的累积和。并检查它是否小于1到子集
library(data.table)
setDT(df)[, .SD[cumsum(is.na(c))<1], by= a]
或者.I
的更快选项,可以返回逻辑向量的行索引并对行进行子集化。
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
答案 1 :(得分:3)
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
行并获得所需的输出。
答案 2 :(得分:3)
基础R中的经典split-apply-combine:
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