在group_by操作之后,dplyr如何为每个组生成数据帧?

cae*_*301 6 r dplyr

流式数据处理中dplyr包的流畅性使我感到非常震惊.最近,我急于为每个组ID生成一个新的数据帧,并将这些小数据帧组合成一个最终的较大数据帧.玩具示例:

input.data.frame %>%
    group_by(gid) %>%
    {some operation to generate a new data frame for each group} ## FAILED!!!!
Run Code Online (Sandbox Code Playgroud)

在dplyr中,mutate向每个组添加新列并为每个组summarise生成摘要的功能都无法满足我的要求.(我错过了什么?)

或者,使用ddplyplyr包,之前的dplyr交互,我可以通过它

ddply(input.data.frame, .(gid), function(x) {
     some operation to generate a new data frame for each group
}
Run Code Online (Sandbox Code Playgroud)

但是当我加载plyr包时,dplyr中的一些功能会被可用性掩盖.

小智 7

以下是G.格洛腾迪克对类似问题的回答.在`dplyr`输出中添加行

首先,我们生成一个带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(.) )
Run Code Online (Sandbox Code Playgroud)


tal*_*lat 3

将我的评论变成答案..

是的,dplyr 提供了一种为每个组创建 data.frames 的方法。在分组的 data.frame / tbl 上使用do运算符可以让您做到这一点,更准确地说,它可以让您将任意函数应用于每个组。这记录在帮助文件中do

[...] 您可以使用 do 执行任意计算,返回数据框或将存储在列表中的任意对象。这在处理模型时特别有用:您可以使用 do 拟合每组模型,然后使用另一个 do 或 summarise 灵活地提取组件。

到目前为止,我的经验是,只要可以使用专门的 dplyr 函数之一,例如 mutate / summarise / mutate_each / 等,就应该优先使用它们do,因为它们通常比使用 更有效do,但当然不如灵活的。

  • 您能否提供您的问题的答案,并显示有关如何使用 do 来执行此操作的代码片段?谢谢 (4认同)