使用2个不符合哪个函数的条件进行子集

时间:2016-07-16 11:53:16

标签: r conditional subset

我一直在尝试在Stackoverflow上找到类似的问题,但所有类似的问题仍然无法解答我的问题或解决此问题。

我有这个数据集,使用which()和其他函数,我试图找到两个条件都为真的id。但是,我无法弄清楚如何让它在R中工作。它要么返回所有id,要么返回我迄今为止尝试过的空矢量。

所以我从我的数据中抽取了20个观察结果只是为了这个问题(实际数据框很大),生成一个模拟样本来传达我的问题并在Stackoverflow上解决它,但我会尝试。

我有这个数据框,我希望id严格包含附件V和附件R.

df
          id attachment 
271  1000534          V      
372  1000547          V      
1012 1000530          R      
1568 1000539          R     
1095 1000530          R      
185  1000534          V      
1476 1000539          R      
903  1000530          R      
309  1000547          V      
1010 1000530          R      
333  1000547          V      
1094 1000530          R      
1334 1000539          R      
340  1000547          V      
730  1000530          R      
22   1000067          V     
1308 1000533          R      
799  1000530          R      
138  1000533          V      
1161 1000530          R      

所以,正如我们所看到的,id 1000533同时包含V和R,因此我想要捕获的id有两种,我尝试了以下选项:

VR <- df[(df$attachment == 'V') & (df$attachment == 'R'),]
VR <- df[(df$attachment == 'V') && (df$attachment == 'R'),]
VR <- df[which(df$attachment == 'V') && which(df$attachment == 'R'),]
VR <- df[which(df$attachment == 'V') & which(df$attachment == 'R'),]

但它们会返回包含所有20个值的数据框。当我打电话

unique(VR$id)

它返回初始数据帧中的所有id。根据我的实际数据,它会返回一个空数据帧,具体取决于我尝试的上述子集尝试中的哪一个,但它永远不会返回我想要的内容 - 仅包含附件V和附件R的id(或观察点)的数据帧

我做错了什么以及如何只提取那些同时拥有V和R的id?

3 个答案:

答案 0 :(得分:4)

由于每次观察只有一个&#34;附件&#34;等级,任何人都不可能同时拥有V和R.

由于ID会在观察中重复出现,因此您可以使用intersect来实现您的目标:

myIds <- intersect(df$id[df$attachment == "V"], df$id[df$attachment == "R"])

现在,myIds将存储同时具有V和R的ID。

myIds
[1] 1000533

这是示例中的单个ID。

如果您希望观察结果只包含V附件而不是R附件,则可以使用setdiff代替intersect

myIds <- setdiff(df$id[df$attachment == "V"], df$id[df$attachment == "R"])

这里要注意的一点是,交叉是可交换的,所以你提供参数的顺序并不重要。对于setdiff,订单很重要。您可以将订单读作参数1中不在参数2中的元素。

答案 1 :(得分:2)

@Imo解决方案当然是最紧凑的。 以下是使用reshape2的变体。它有额外的信息,提供每个ID /附件组合出现的次数:

library(reshape2)
output <- dcast(df, id ~ attachment)

output
  id      R V
1 1000067 0 1
2 1000530 8 0
3 1000533 1 1
4 1000534 0 2
5 1000539 3 0
6 1000547 0 4

要查找包含两个附件的ID:

output$id[output$R != 0 & output$V != 0]
[1] 1000533

要查看哪些ID具有附件V而不是R:

output$id[output$R == 0 & output$V != 0]

要查看哪些ID具有附件R而不是V:

output$id[output$R != 0 & output$V == 0]

答案 2 :(得分:2)

以下是dplyr

的方法
library(dplyr)
df %>%
  group_by(id) %>%
  mutate(a = sort(paste0(unique(attachment), collapse = ""))) 

返回:

        id attachment     a
     <int>     <fctr> <chr>
1  1000534          V     V
2  1000547          V     V
3  1000530          R     R
4  1000539          R     R
5  1000530          R     R
6  1000534          V     V
7  1000539          R     R
8  1000530          R     R
9  1000547          V     V
10 1000530          R     R
11 1000547          V     V
12 1000530          R     R
13 1000539          R     R
14 1000547          V     V
15 1000530          R     R
16 1000067          V     V
17 1000533          R    RV
18 1000530          R     R
19 1000533          V    RV
20 1000530          R     R

现在,您可以filtera,无论您喜欢什么条件。在这种情况下,只能获得idsV的{​​{1}}。

R

您可以将过滤条件更改为仅查找df %>% group_by(id) %>% mutate(a = sort(paste0(unique(attachment), collapse = ""))) %>% filter(a == "RV") %>% ungroup() %>% distinct(id) 或其他任何内容。