【问题标题】:bind columns returned by do/tidy from dplyr and broom not working as expecteddo/tidy 从 dplyr 和 broom 返回的绑定列未按预期工作
【发布时间】:2016-05-24 21:26:57
【问题描述】:

我正在尝试使用来自dplyrdo 和来自broomtidy 将一些东西整齐地组织到一个数据框中。一切正常。但是,现在我正在尝试根据同一管道内的分组来改变一个值,但我无法让它为我想要的工作:

示例(带有mtcars 数据集):

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

我希望得到每个 cyl 的 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))))

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

【问题讨论】:

  • 或者简单地说:mtcars %&gt;% group_by(cyl) %&gt;% mutate(n = n()) %&gt;% group_by(cyl,n) %&gt;% do(tidy(summary(.$mpg)))
  • 肯定更好...仍然希望有一种方法可以获取do 的输出和列绑定。 ?do 确实说它返回一个数据框。
  • 带data.table:as.data.table(mtcars)[, c(.(n = .N), as.list(summary(mpg))), by=cyl]

标签: r dplyr broom


【解决方案1】:

do 中使用bind_cols

 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

【讨论】:

  • mtcars %&gt;% group_by(cyl) %&gt;% group_by(n = n(), add = TRUE) %&gt;% do(tidy(summary(.$mpg)))简化
  • @coffeinjunky 这是一个很好的解决方案,比我提出的inner_join 解决方案更好。希望找到一种方法来避免重新指定n。但是,如果无法避免,我同意,这是一个很好的答案。
  • @Frank 你的是迄今为止我见过的最好的,而其他的比我最初想出的更好。
  • 我实际上比上面更喜欢使用n 作为分组变量。我认为主要的收获是对管道数据帧的任意操作应该在do 内部,而不是在do 周围。不过,我相信其他人可以比我更好地解释所涉及的复杂性。
  • 我在这里发表了评论,以便您可以根据需要添加/修改它。
【解决方案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。)

【讨论】:

  • 可能包作者会坚持只有高级用户同时需要summaryn。这就是您注册 dplyr 时所做的交易——您获得了用于数据操作的连贯语法,但缺少整个词性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 2015-12-03
相关资源
最近更新 更多