【问题标题】:R dplyr filter requires stored filter conditionR dplyr 过滤器需要存储过滤条件
【发布时间】:2017-11-16 06:55:27
【问题描述】:

当我过滤条件由其他过滤器组成的数据框时,它似乎不起作用。但是,如果我将条件存储为变量(示例中为f),则过滤工作正常。有人可以解释为什么会发生这种情况,以及如何使示例 2 之类的东西起作用吗?我宁愿不将过滤条件存储为变量。

library(dplyr)

# Dummy data set
df <- data.frame(Country = factor(c("Argentina", "Brazil", "Brazil", "Brazil")), 
                 Type = factor(c("A", "A", "B", "C")))

# Only returns Brazil. No problem here.
f <- df %>% 
  group_by(Country) %>% 
  summarise(nTypes = n_distinct(Type)) %>% 
  filter(nTypes==3) %>% 
  select(Country) %>% 
  droplevels() %>% 
  unlist()
# > f
#   Country 
# Brazil 
# Levels: Brazil


# Example 1 - Only returns rows of df where Country=="Brazil". No problem here.
df %>% filter(
  Country %in% (f
                )
  )
#   Country Type
# 1  Brazil    A
# 2  Brazil    B
# 3  Brazil    C


# Example 2 - Filter is equivalent to `f` but returns all rows of df, not just Brazil. No idea why!
df %>% filter(
  Country %in% (df %>% 
                  group_by(Country) %>% 
                  summarise(nTypes = n_distinct(Type)) %>% 
                  filter(nTypes==3) %>% 
                  select(Country) %>% 
                  droplevels() %>% 
                  unlist()
                )
  )
#     Country Type
# 1 Argentina    A
# 2    Brazil    A
# 3    Brazil    B
# 4    Brazil    C

【问题讨论】:

  • 您到底想得到什么 - 显示类型为 3 的国家/地区列表?
  • 奇怪,我怀疑这是 NSE 名称冲突,但我不确定具体如何。无论如何,您可以将整个事情简化为df %&gt;% group_by(Country) %&gt;% filter(n_distinct(Type) == 3)
  • ...或者只是翻转订单并将f的代码输入{ filter(df, Country %in% .) }
  • @amrrs 我试图获得与示例 1 相同的输出,但使用示例 2 中所示的方法。也就是说,不将过滤条件存储为变量
  • @alistaire 您的第一条评论效果很好!我想我可能过于复杂了。尽管如此,我的问题中的例子还是很奇怪。

标签: r filter dplyr


【解决方案1】:

虽然我不确定您为什么会得到意想不到的结果,但基于此答案:Using filter inside filter in dplyr gives unexpected results 在filtering 之后获得所需结果的一种方法是使用inner_join

df %>% 
  group_by(Country) %>% 
  summarise(nTypes = n_distinct(Type)) %>% 
  filter(nTypes==3) %>% 
  select(Country) %>% inner_join(.,df)

输出:

Joining, by = "Country"
# A tibble: 3 x 2
  Country   Type
   <fctr> <fctr>
1  Brazil      A
2  Brazil      B
3  Brazil      C

【讨论】:

  • 这行得通,谢谢@amrrs!我还将向任何未来的读者说明,@alistaire 在 cmets 中的解决方案也可以工作,而且我认为更容易阅读、理解,而且很可能更快,因为不需要加入。
  • 如果您愿意,也可以随意编辑答案!
猜你喜欢
  • 2017-05-06
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多