由于NA,无法对数据帧进行子集(过滤)

时间:2016-08-15 01:33:32

标签: r data.table dplyr subset

为什么在下面的代码中,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),]

3 个答案:

答案 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