子集有 2 个条件不适用于哪个功能

Subsetting with 2 conditions not working with which function

我一直试图在 Whosebug 上找到类似的问题,但所有类似的问题仍然没有回答我的问题或解决这个问题。

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

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

我有这个数据框,我想要严格包含附件 V 和附件 R 的 ID。

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'),]

但他们 return 一个包含所有 20 个值的数据框。当我打电话给

unique(VR$id)

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

我做错了什么以及如何只提取同时具有 V 和 R 的 ID?

由于每个观测值只有一个"attachment"水平,因此不可能同时具有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 attachment 而没有 R attachment,你可以使用 setdiff 而不是 intersect:

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

这里要注意的一件事是交集是可交换的,因此输入参数的顺序无关紧要。对于 setdiff,顺序很重要。您可以将顺序读取为参数 1 中不在参数 2 中的元素。

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

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]

这是 dplyr

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

哪个returns这个:

        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

现在您可以在 a 列中 filter 满足您喜欢的任何条件。在这种情况下,仅获取具有 VR.

ids
df %>%
  group_by(id) %>%
  mutate(a = sort(paste0(unique(attachment), collapse = ""))) %>%
  filter(a == "RV") %>%
  ungroup() %>%
  distinct(id)

您可以将筛选条件更改为仅查找 V 或其他任何内容。