通过(行)对的组合进行过滤

rct*_*oni 3 r subset dplyr tidyr tidyverse

我有一个长格式的数据帧,我想根据值的唯一组合过滤对.我有一个如下所示的数据集:

id <- rep(1:4, each=2)
type <- c("blue", "blue", "red", "yellow", "blue", "red", "red", "yellow")
df <- data.frame(id,type)
df
  id   type
1  1   blue
2  1   blue
3  2    red
4  2 yellow
5  3   blue
6  3    red
7  4    red
8  4 yellow
Run Code Online (Sandbox Code Playgroud)

假设每个id都是一个响应者,type是一种治疗组合.个人1看到两个物体,都是蓝色的; 个人2看到一个红色物体和一个黄色物体; 等等.

例如,如何看到那些看到"红色"和"黄色"组合的东西?如果我按"红色"和"黄色"组合过滤,结果数据集应如下所示:

  id   type
3  2    red
4  2 yellow
7  4    red
8  4 yellow
Run Code Online (Sandbox Code Playgroud)

它应该保留2号和4号受访者(只有那些看到"红色"和"黄色"组合的受访者).请注意,它不会保留第3号受访者,因为她看到"蓝色"和"红色"(而不是"红色"和"黄色").我该怎么做呢?

一种解决方案是将数据集重新整形为宽格式,按列过滤,然后重新进行重新打包.但我相信还有另一种方法可以在不重塑数据集的情况下完成.任何的想法?

Dav*_*vid 6

一个dplyr解决办法是:

library(dplyr)
df <- data_frame(
  id = rep(1:4, each = 2),
  type = c("blue", "blue", "red", "yellow", "blue", "red", "red", "yellow")
)

types <- c("red", "yellow")

df %>% 
  group_by(id) %>% 
  filter(all(types %in% type))
#> # A tibble: 4 x 2
#> # Groups:   id [2]
#>      id   type
#>   <int>  <chr>
#> 1     2    red
#> 2     2 yellow
#> 3     4    red
#> 4     4 yellow
Run Code Online (Sandbox Code Playgroud)

更新

允许相等的组合,例如blue,blue我们必须将filter-call更改为以下内容:

types2 <- c("blue", "blue")

df %>% 
  group_by(id) %>% 
  filter(sum(types2 == type) == length(types2))
#> # A tibble: 2 x 2
#> # Groups:   id [1]
#>      id  type
#>   <int> <chr>
#> 1     1  blue
#> 2     1  blue
Run Code Online (Sandbox Code Playgroud)

该解决方案还允许不同类型

df %>% 
  group_by(id) %>% 
  filter(sum(types == type) == length(types))
#> # A tibble: 4 x 2
#> # Groups:   id [2]
#>      id   type
#>   <int>  <chr>
#> 1     2    red
#> 2     2 yellow
#> 3     4    red
#> 4     4 yellow
Run Code Online (Sandbox Code Playgroud)