使用dplyr按相同的分组变量过滤两个数据框。

4

在许多情况下,对于某些变量对数据帧进行分组后,我希望应用一个使用来自另一个按相同变量分组的数据帧的数据的函数。我找到的最佳解决方案是在函数内部使用 semi_join 如下:

d1 <- data.frame(model = c(1,1,2,2), x = runif(4) )
d2 <- data.frame(model=c(1,1,1,2,2,2), y = runif(6) )

myfun <- function(df1, df2) {
   subsetdf2 <- semi_join(df2, df1)
   data.frame(z = sum(d1$x) - sum(subsetdf2$y)) # trivial manipulation just to exemplify
}

d1 %>% group_by(model) %>% do(myfun(., d2))

问题在于semi_join返回“Joining by…”信息,而我正在使用该函数进行引导程序,导致控制台崩溃了很多信息。那么,有没有办法减少连接的冗长性?您知道更优雅的方式来做这样的事情吗?
附言:我几年前曾经为plyr提出过类似的问题:subset inside a function by the variables specified in ddply

在你的例子中,d2没有按任何变量分组。 - talat
我认为它隐式地与 semi_join 函数一起分组在函数内部。 - danilinares
1
如果你想要摆脱这些消息,那么请明确你正在连接哪些变量。 - hadley
现在,我正在使用 purrr 包中的 map2 解决这种问题。 - danilinares
2个回答

2
如果您只想停止“Joining by:”语句,您只需要使用“by”参数指定要加入的列即可。
例如:
semi_join(d2, d1, by="model")

编辑 - 作为使用 semi_join 的替代方案,您可以使用一个 base 解决方案。由于 group_by 函数按组传递数据,因此可以使用简单的索引语句进行过滤。这将避免需要额外的参数。 这也假定感兴趣的列是第一列。

myfun <- function(df1, df2) {
  subsetdf2 <- df2[df2[,1] %in% unique(df1[,1]),]
  data.frame(z = sum(df1$x) - sum(subsetdf2$y)) # trivial manipulation just to exemplify
}

我不想在函数内明确使用“model”。我猜可以使用类似group_var='model'的东西,然后像d1%>%group_by_(group_var)%>%do(myfun(。,d2,group_var))一样,在函数内最终使用group_bar进行连接,但这似乎不太整洁。 - danilinares
@danilinares,你能否更新一下你的问题,说明你希望最终函数的结构是怎样的?你目前在当前解决方案中直接使用了模型,所以我没有尝试避免它。 - cdeterman
抱歉,我不太理解您关于更改问题的建议。我不想在'myfun'内手动引入分组变量。在我提出的尝试中,数据框df2通过do()的分组变量进行过滤,而无需明确指定哪些是分组变量。 - danilinares
@danilinares,上面的编辑是否已经充分解决了你的问题? - cdeterman
我正在寻找更通用的东西,但是像我在后续评论中所说的那样扩展您的第一个解决方案对我来说已经足够好了(我将其发布为可能的解决方案)。 - danilinares

0
我采用了@cdeterman的解决方案。虽然有点冗余。
d1 <- data.frame(model = c(1,1,2,2), x = runif(4) )
d2 <- data.frame(model=c(1,1,1,2,2,2), y = runif(6) )

myfun <- function(df1, df2, gv) {
  subsetdf2 <- semi_join(df2, df1, by = gv)
  data.frame(z = sum(d1$x) - sum(subsetdf2$y)) # trivial manipulation just to     exemplify
}

group_var <- 'model'
d1 %>% group_by_(group_var) %>% do(myfun(., d2,group_var))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接