绑定do / tidy从dplyr和broom返回的列不能按预期工作

时间:2016-05-24 21:26:57

标签: r dplyr broom

我正在尝试使用do中的dplyrtidy中的broom将一些内容整齐地组织到数据框中。一切正常。但是,现在我试图根据同一个管道内的分组来改变一个值,我不能让它适合我想要的东西:

示例(mtcars数据集设置):

library(dplyr)
library(broom)
mtcars %>% group_by(cyl) %>% mutate(n = n()) %>% do(tidy(summary(.$mpg)))

我希望得到每个summary的输出以及我在中间计算的观察次数。但是,我只得到summary的输出如下:

Source: local data frame [3 x 7]
Groups: cyl [3]

    cyl minimum    q1 median  mean    q3 maximum
  <dbl>   <dbl> <dbl>  <dbl> <dbl> <dbl>   <dbl>
1     4    21.4 22.80   26.0 26.66 30.40    33.9
2     6    17.8 18.65   19.7 19.74 21.00    21.4
3     8    10.4 14.40   15.2 15.10 16.25    19.2

缺少输出值n

我还尝试了bind_colsinner_join,如下所示,两者都会导致错误:

mtcars %>% group_by(cyl) %>% mutate(mpgMean = mean(mpg)) %>% inner_join(., do(tidy(summary(.$mpg))))
Error in args[[1]] : subscript out of bounds
mtcars %>% group_by(cyl) %>% mutate(n = n()) %>% bind_cols(do(tidy(summary(.$mpg))))
Error in args[[1]] : subscript out of bounds

知道如何让这项工作成功吗?

我的预期输出是:

Joining by: "cyl"
Source: local data frame [3 x 8]

    cyl     n minimum    q1 median  mean    q3 maximum
  <dbl> <int>   <dbl> <dbl>  <dbl> <dbl> <dbl>   <dbl>
1     4    11    21.4 22.80   26.0 26.66 30.40    33.9
2     6     7    17.8 18.65   19.7 19.74 21.00    21.4
3     8    14    10.4 14.40   15.2 15.10 16.25    19.2

当然,我可以得到这样的结果:

inner_join(count(mtcars, cyl), mtcars %>% group_by(cyl) %>% do(tidy(summary(.$mpg))))

但是,寻找单管道解决方案(如果可能的话)。

2 个答案:

答案 0 :(得分:2)

bind_cols

中使用do
 mtcars %>% group_by(cyl) %>% 
            mutate(n = n()) %>% 
            do(bind_cols(tidy(summary(.$mpg)), 
                         data.frame(unique(.$n)) ))

或(首选项)使用n作为分组变量(由@Frank提供):

 mtcars %>% group_by(cyl) %>% 
            group_by(n = n(), add=T) %>% 
            do(tidy(summary(.$mpg)))

两者都给:

Source: local data frame [3 x 8]
Groups: cyl, n [3]

    cyl     n minimum    q1 median  mean    q3 maximum
  (dbl) (int)   (dbl) (dbl)  (dbl) (dbl) (dbl)   (dbl)
1     4    11    21.4 22.80   26.0 26.66 30.40    33.9
2     6     7    17.8 18.65   19.7 19.74 21.00    21.4
3     8    14    10.4 14.40   15.2 15.10 16.25    19.2

答案 1 :(得分:2)

我担心惯用的方式是

my_summary = function(x) as.data.frame(as.list(c(n = length(x), summary(x))))
mtcars %>% group_by(cyl) %>% do(my_summary(.$mpg))

    cyl     n  Min. X1st.Qu. Median  Mean X3rd.Qu.  Max.
  (dbl) (dbl) (dbl)    (dbl)  (dbl) (dbl)    (dbl) (dbl)
1     4    11  21.4    22.80   26.0 26.66    30.40  33.9
2     6     7  17.8    18.65   19.7 19.74    21.00  21.4
3     8    14  10.4    14.40   15.2 15.10    16.25  19.2

(我不熟悉broom使用它来编写my_summary。)