【问题标题】:How to use anti_join with different levels of two variables?如何使用具有不同级别的两个变量的anti_join?
【发布时间】:2021-09-25 08:51:26
【问题描述】:

我已经尝试了几个小时,但我无法弄清楚。我有一个包含主题和条件df1 的数据框,我想从中排除具有特定值的观察值(df2 的变量“值”中小于 3。我无法使其工作,因为我需要删除来自df1,两个变量不同层次的组合。

这是 df1:

df1 <- structure(list(subject = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,2L, 2L, 2L, 2L, 
                                  2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), 
                      condition = c("A", "A", "A", "B", "B", "B", "C", "C","C", "A", "A", 
                                    "A", "B", "B", "B", "C", "C", "C", "A", "A", "A","B", "B", "B", "C", "C", "C")), 
                 row.names = c(NA, -27L), class = c("tbl_df", "tbl", "data.frame"))

这是 df2

df2 <- structure(list(subject = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L,4L, 4L, 4L, 5L, 5L, 5L), 
                      condition = c("A", "B", "C", "A", "B","C", "A", "B", "C", "A", "B", "C", "A", "B", "C"), 
                      value = c(10L, 8L, 7L, 3L, 8L, 5L, 3L, 3L, 9L, 8L, 7L, 8L, 10L, 6L, 2L)), 
                 row.names = c(NA,-15L), class = c("tbl_df", "tbl", "data.frame"))

我想在df1 中删除所有低于 3 的主题和条件组合,所以这将是最终的 df:

df3 <- structure(list(subject = c(2L, 3L, 3L, 5L), 
                      condition = c("A","A", "B", "C")), 
                 row.names = c(NA, -4L), 
                 class = c("tbl_df","tbl", "data.frame"))

到目前为止,我一直在这样做,但我不能再这样做了,因为我有数百行......

df3 <- df1 %>% filter(!(subject==2 & condition=="A" |
                        subject==3 & (condition=="A" | condition=="B") |
                        subject==5 & condition=="C"))

【问题讨论】:

  • 您好,感谢您提供可重现的数据。特别感谢您在重新格式化来自dput() 的文本方面所做的努力!只是为了澄清一下:您是说您当前的解决方案不准确,它在数百行上的性能很差,或者它是不可扩展到数百行中的更多行?
  • 仅供参考,我认为您的意思是说 " 小于 [或等于] 3 在变量 value 中来自 df2"。只有不等式 &lt;= 3 会给你描述的结果。
  • 你好。它的性能很差,因为它依赖于我重新排列 df2,然后在顶部手写主题和条件的组合(因此小于或等于 3 的组合)。

标签: r tidyverse anti-join


【解决方案1】:

df3 的示例结果与您用于派生它的代码冲突,因此这里有一个 dplyr 解决方案,用于对您想要的 df3 的每种解释。

注意:只有当你

...从df2中排除变量“value”中具有特定值(小于[或等于] 3的观察值。

所以我使用不等式 &lt;= 3 而不是 &lt; 3 来实现这些解决方案。

第一次解释df3

获取df3的版本

# A tibble: 4 x 2
  subject condition
    <int> <chr>    
1       2 A        
2       3 A        
3       3 B        
4       5 C        

您在此处提供的示例结果

我想在 df1 中删除所有低于 3 的主题和条件组合,所以 这将是最终的 df

df3 <- structure(list(subject = c(2L, 3L, 3L, 5L), 
                      condition = c("A","A", "B", "C")), 
                 row.names = c(NA, -4L), 
                 class = c("tbl_df","tbl", "data.frame"))

只需在df2 上使用filter()

library(dplyr)


# ...
# Code to generate 'df1' and 'df2'.
# ...

df3 <- df2 %>% filter(value <= 3)

第二次解读df3

但是,我看来您实际上想要以下版本的df3

# A tibble: 18 x 2
   subject condition
     <int> <chr>    
 1       1 A        
 2       1 A        
 3       1 A        
 4       1 B        
 5       1 B        
 6       1 B        
 7       1 C        
 8       1 C        
 9       1 C        
10       2 B        
11       2 B        
12       2 B        
13       2 C        
14       2 C        
15       2 C        
16       3 C        
17       3 C        
18       3 C        

你在这里得到的:

df3 <- df1 %>% filter(!(subject==2 & condition=="A" |
                        subject==3 & (condition=="A" |condition=="B") |
                        subject==5 & condition=="C"))

那种的情况下,你应该把anti_join()你的df1改成filter()ed版本的df2

library(dplyr)


# ...
# Code to generate 'df1' and 'df2'.
# ...


df3 <- df1 %>%
  anti_join(df2 %>% filter(value <= 3), by = c("subject", "condition"))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-10
    • 2022-01-16
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 2021-12-16
    相关资源
    最近更新 更多