为什么在下面的代码中,dplyr' s filter
没有返回与基本R子集相同的data.frame?
事实上,它们都没有按预期工作。我想同时移除观察/行b==1 AND c==1
。也就是说,我只想删除第三行。
require(dplyr)
df <- data.frame(a=c(0,0,0,0,1,1,1), b=c(0,0,1,1,0,0,1), c=c(1,NA,1,NA,1,NA,NA))
filter(df, !(b==1 & c==1))
df[!(df$b==1 & df$c==1),]
答案 0 :(得分:3)
或者使用complete.cases
在结果逻辑向量中将NA
转换为FALSE
,以便您可以在否定后选择相应的行,并使用{{1 }}:
NA & F = F
此处涉及filter(df, !(b == 1 & c == 1 & complete.cases(df[c('b', 'c')])))
# a b c
# 1 0 0 1
# 2 0 0 NA
# 3 0 1 NA
# 4 1 0 1
# 5 1 0 NA
# 6 1 1 NA
的更多逻辑操作,乍一看有点令人困惑,但他们遵循逻辑:
NA
答案 1 :(得分:2)
使用data.table
library(data.table)
setDT(df)[df[,!(b==1 & c== 1& complete.cases(.SD[, c('b', 'c'), with = FALSE]))]]
# a b c
#1: 0 0 1
#2: 0 0 NA
#3: 0 1 NA
#4: 1 0 1
#5: 1 0 NA
#6: 1 1 NA
答案 2 :(得分:1)
是的,NA
值会导致问题。这里有4个解决方法:
方法1:两步排除
n <- (df$b+df$c==2)
df[n %in% c(NA, "FALSE"),]
a b c 1 0 0 1 2 0 0 NA 4 0 1 NA 5 1 0 1 6 1 0 NA 7 1 1 NA
方法2:条件总和
df[!(complete.cases(df$b,df$c) & df$b+df$c == 2),]
a b c 1 0 0 1 2 0 0 NA 4 0 1 NA 5 1 0 1 6 1 0 NA 7 1 1 NA
方法3:循环/功能
filterwithNA <- function(df,n){
for(i in 1:nrow(df)){
if(!is.na(df$b[i]) & !(is.na(df$c[i]))){
if(df$b[i] == n & df$c[i] == n){
df <- df[-i,]
}
}
}
return(df)
}
filterwithNA(df, n=1)
a b c 1 0 0 1 2 0 0 NA 4 0 1 NA 5 1 0 1 6 1 0 NA 7 1 1 NA
方法4:临时数字替换
df[is.na(df)] <- 999
df[!(df$b==1 & df$c==1),]
df[df==999] <- NA
df
a b c 1 0 0 1 2 0 0 NA 4 0 1 NA 5 1 0 1 6 1 0 NA 7 1 1 NA