我对流式数据处理中dplyr包的流畅性感到震惊。最近,我急于为每个组ID生成一个新的数据帧,并将这些小数据帧组合成一个最终的较大数据帧。玩具示例:
input.data.frame %>%
group_by(gid) %>%
{some operation to generate a new data frame for each group} ## FAILED!!!!
在dplyr中,函数mutate
向每个组添加新列,summarise
为每个组生成摘要,两者都无法满足我的要求。 (我错过了什么吗?)
或者,使用plyr包的ddply
,之前的dplyr交互,我可以通过
ddply(input.data.frame, .(gid), function(x) {
some operation to generate a new data frame for each group
}
但是当我加载plyr包时,dplyr中的一些功能会因可用性而被屏蔽掉。
答案 0 :(得分:6)
以下是G.格洛腾迪克对类似问题的回答。 Adding rows in `dplyr` output
首先,我们使用x和g生成数据框。 x中有9个随机数,g中有3个组a,b,c。我们想从每个组中选择2个最大的数字。重要的是要记住,确实需要数据框作为返回值。
library(dplyr)
set.seed(1)
dat <- data.frame(x=runif(9),g=rep(letters[1:3],each=3))
dat
x g
1 0.1765568 a
2 0.6870228 a
3 0.3841037 a
4 0.7698414 b
5 0.4976992 b
6 0.7176185 b
7 0.9919061 c
8 0.3800352 c
9 0.7774452 c
## this works
dat %>% dplyr::group_by( g ) %>% do( data.frame(x=tail(sort(.$x),2)) )
## this works too
dat %>% dplyr::group_by( g ) %>% do( .[tail(order(.$x),2),] )
x g
(dbl) (fctr)
1 0.3841037 a
2 0.6870228 a
3 0.7176185 b
4 0.7698414 b
5 0.7774452 c
6 0.9919061 c
## no error, but x is treated as a 1x1 data frame
dat %>% dplyr::group_by( g ) %>% do( x=tail(sort(.$x),2) )
g x
(fctr) (chr)
1 a <dbl[2]>
2 b <dbl[2]>
3 c <dbl[2]>
## you need a function to do more complicated stuff
top2x <- function(df) { df[tail(order(df$x),2),] }
dat %>% dplyr::group_by( g ) %>% do( top2x(.) )
答案 1 :(得分:3)
将我的评论转化为答案..
是的,dplyr提供了一种为每个组创建data.frames的方法。在分组的data.frame / tbl上使用do
运算符将允许您执行此操作,更准确地说,它允许您将任意函数应用于每个组。这在do
的帮助文件中记录:
[...]你可以用do来执行任意计算,返回a 数据框或将存储在列表中的任意对象。这个 在使用模型时特别有用:您可以适合模型 每组用do,然后用其中任何一个灵活地提取组件 另一个做或总结。
到目前为止,我的经验是,只要有可能使用其中一个专门的dplyr函数,如mutate / summarize / mutate_each /等,它们应优先于do
,因为它们通常比使用do
,但当然不是那么灵活。