使用dplyr或R中的其他包进行子集化

时间:2015-04-30 11:22:52

标签: r dplyr

所以我们有这个基本数据

A <- c(1,1,1,2,2,2,3,3,3)
B <- c(1,0,0,1,0,0,1,0,0)
C <- c(2,2,3,4,3,3,3,4,3)
Data <- data.frame(A,B,C)

我们现在想要过滤它

我们看每个C = 3和B = 1的情况 并找到它一个值 使用此A值,我们要搜索C = 4和B = 0并删除它

如此图形化,

enter image description here

我们要删除红色行并保持绿色行

我理想地想要使用dplyr但是对其他替代方案开放

5 个答案:

答案 0 :(得分:4)

Base R,我认为这就是你所需要的:

# Column A values to consider for filter
C3_B1 <- Data[Data$C==3 & Data$B==1,"A"]

# Filter out rows where C==4 and B==0
Data[ !(Data$A %in% C3_B1 &
          Data$C==4 &
          Data$B==0),]

# Output - row 8 is removed
#   A B C
# 1 1 1 2
# 2 1 0 2
# 3 1 0 3
# 4 2 1 4
# 5 2 0 3
# 6 2 0 3
# 7 3 1 3
# 9 3 0 3

使用sqldf包:

sqldf(c("DELETE FROM Data 
          WHERE A IN (SELECT A FROM Data 
                       WHERE  C = 3 AND B = 1) 
                AND C = 4 
                AND B = 0",
        "SELECT * FROM Data "))

答案 1 :(得分:2)

使用dplyr

Data %>% filter(!(A==select(filter(Data, C==3 & B==1), A)[,1] & C==4 & B ==0))

本质上是一个两步过程。

第一个是:

select(filter(Data, C==3 & B==1), A)

过滤DataC==3B==1,然后只选择列A。我们将此命名为temp

第二步是:

Data %>% filter(!(A==temp[,1] & C==4 & B ==0))

一个简单的过滤。

答案 2 :(得分:2)

这是另一种data.table方法。首先,将其读取为键控data.table:

require(data.table)
DT <- data.table(Data,key="C,B,A")

识别OP不喜欢的A值

myA <- DT[J(3,1)]$A

排除

DT[!J(4,0,myA)]

如果myA是向量,这也可以。

答案 3 :(得分:1)

你提到了其他选择,所以这里是data.table

library(data.table)
 d=as.data.table(Data)
 d[!((A==d[B==1 & C==3,A])&(C==4&B==0))]

但不确定这将如何处理更复杂的情况,并删除更多行。

答案 4 :(得分:0)

另一个解决方案,可能比上面的一些解决方案慢一些。但对读者来说可能会更加透明。如果要运行不同的B和C值,也更容易进入函数。

a_values <- Data %>% 
  filter(B == 1, C == 3) %>% 
  select(A) %>% 
  unique()

Data <- Data %>% 
  filter(!(A %in% a_values & B == 0 & C == 4))

编辑:忘了否定!