使用R 3.1.2
,dplyr 0.4.0
。
我试图在filter
内使用filter
,这听起来非常简单,我不明白为什么它没有给我我预期的结果。这是我在6个月前写的代码,我相当确定它有用,所以要么因为更新的R版本或dplyr
或其他依赖项而停止工作。无论如何,这里有一些简单的代码,它根据在df2中的列上filter
找到的条件来过滤来自df1的行。
df1 <- data.frame(x = c("A", "B"), stringsAsFactors = FALSE)
df2 <- data.frame(x = "A", y = TRUE, stringsAsFactors = FALSE)
dplyr::filter(df1, x %in% (dplyr::filter(df2, y)$x))
我希望这会显示df1
的第一行,但我会得到
# [1] x
# <0 rows> (or 0-length row.names)
我不知道该怎么做。为什么它返回一个向量和一个空的data.frame?
如果我将过滤器代码分解为两个单独的语句,我得到了我期望的结果
xval <- dplyr::filter(df2, y)$x
dplyr::filter(df1, x %in% xval)
# x
# 1 A
任何人都可以帮我弄清楚为什么会发生这种行为?我不是说这是一个错误,但我不明白。
答案 0 :(得分:4)
这是一个有效的问题,为什么你的方法不起作用(显然)。我无法回答这个问题,但我建议采用不同的方法,如上所述,它避免了嵌套函数调用(filter
在另一个filter
内),IMO,是dplyr的用途:通过易于阅读和理解语法表达,从左到右,从上到下。
因此,对于您的示例,因为您感兴趣的列都被命名为&#34; x&#34;你可以这样做:
filter(df2, y) %>% select(x) %>% inner_join(df1)
如果它们不同,例如&#34; z&#34;和&#34; x&#34;你可以使用:
filter(df2, y) %>% select(x) %>% inner_join(df1, by = c("z" = "x"))
正如哈德利在下面的评论中指出的那样,在这里使用semi_join
代替inner_join
会更安全。文档说:
semi_join:返回x中y所有匹配值的所有行, 只保留x中的列。
半连接与内连接不同,因为内连接将是 为y的每个匹配行返回一行x,其中半连接将为 永远不要复制x行。
因此,您可以为示例案例做到:
filter(df2, y) %>% select(x) %>% semi_join(df1)