我在下面的示例中有一个数据框ex_data
,其中列出了参与者ID,组标识符和一些值。然后,我有第二个数据框,指示需要删除的特定观察(在下面的示例中为remove_data
)。有没有办法使用 dplyr 或其他 tidyverse 函数来过滤掉这些组合?在下面的努力中,我最终过滤掉所指示参与者的所有记录,而不仅仅是参与者在该特定组中的数据。我能够使用for循环获得所需的输出,我也将其作为参考。
library(tidyverse)
#> Loading tidyverse: ggplot2
#> Loading tidyverse: tibble
#> Loading tidyverse: tidyr
#> Loading tidyverse: readr
#> Loading tidyverse: purrr
#> Loading tidyverse: dplyr
#> Conflicts with tidy packages ----------------------------------------------
#> filter(): dplyr, stats
#> lag(): dplyr, stats
set.seed(1234)
ex_data <- data_frame(
id = rep(sample(1:100, 10), 2),
group = rep(c("a", "b"), each = 10),
score = rnorm(20)
)
ex_data
#> # A tibble: 20 x 3
#> id group score
#> <int> <chr> <dbl>
#> 1 12 a 0.50605589
#> 2 62 a -0.57473996
#> 3 60 a -0.54663186
#> 4 61 a -0.56445200
#> 5 83 a -0.89003783
#> 6 97 a -0.47719270
#> 7 1 a -0.99838644
#> 8 22 a -0.77625389
#> 9 99 a 0.06445882
#> 10 47 a 0.95949406
#> 11 12 b -0.11028549
#> 12 62 b -0.51100951
#> 13 60 b -0.91119542
#> 14 61 b -0.83717168
#> 15 83 b 2.41583518
#> 16 97 b 0.13408822
#> 17 1 b -0.49068590
#> 18 22 b -0.44054787
#> 19 99 b 0.45958944
#> 20 47 b -0.69372025
remove_data <- data_frame(
id = sample(ex_data$id, 3),
group = sample(c("a", "b"), 3, replace = TRUE)
)
remove_data
#> # A tibble: 3 x 2
#> id group
#> <int> <chr>
#> 1 62 b
#> 2 97 a
#> 3 60 b
# Current efforts
ex_data %>%
filter(!(id %in% remove_data$id & group %in% remove_data$group))
#> # A tibble: 14 x 3
#> id group score
#> <int> <chr> <dbl>
#> 1 12 a 0.50605589
#> 2 61 a -0.56445200
#> 3 83 a -0.89003783
#> 4 1 a -0.99838644
#> 5 22 a -0.77625389
#> 6 99 a 0.06445882
#> 7 47 a 0.95949406
#> 8 12 b -0.11028549
#> 9 61 b -0.83717168
#> 10 83 b 2.41583518
#> 11 1 b -0.49068590
#> 12 22 b -0.44054787
#> 13 99 b 0.45958944
#> 14 47 b -0.69372025
# Desired output
for (i in 1:nrow(remove_data)) {
ex_data <- ex_data %>%
filter(!(id == remove_data$id[i] & group == remove_data$group[i]))
}
ex_data
#> # A tibble: 17 x 3
#> id group score
#> <int> <chr> <dbl>
#> 1 12 a 0.50605589
#> 2 62 a -0.57473996
#> 3 60 a -0.54663186
#> 4 61 a -0.56445200
#> 5 83 a -0.89003783
#> 6 1 a -0.99838644
#> 7 22 a -0.77625389
#> 8 99 a 0.06445882
#> 9 47 a 0.95949406
#> 10 12 b -0.11028549
#> 11 61 b -0.83717168
#> 12 83 b 2.41583518
#> 13 97 b 0.13408822
#> 14 1 b -0.49068590
#> 15 22 b -0.44054787
#> 16 99 b 0.45958944
#> 17 47 b -0.69372025
答案 0 :(得分:4)
为什么不使用anti_join
代替filter
?
dplyr::anti_join(ex_data, remove_data)
Joining, by = c("id", "group")
# A tibble: 17 x 3
id group score
<int> <chr> <dbl>
1 47 b -0.69372025
2 99 b 0.45958944
3 22 b -0.44054787
4 1 b -0.49068590
5 97 b 0.13408822
6 83 b 2.41583518
7 61 b -0.83717168
8 12 b -0.11028549
9 47 a 0.95949406
10 99 a 0.06445882
11 22 a -0.77625389
12 1 a -0.99838644
13 83 a -0.89003783
14 61 a -0.56445200
15 60 a -0.54663186
16 62 a -0.57473996
17 12 a 0.50605589