在dplyr中对具有多个输出的函数进行有效赋值,使其突变或汇总

在dplyr中对具有多个输出的函数进行有效赋值,使其突变或汇总,r,dplyr,R,Dplyr,我注意到这里有很多例子,它们使用dplyr::mutate与返回多个输出的函数组合来创建多个列。例如: tmp <- mtcars %>% group_by(cyl) %>% summarise(min = summary(mpg)[1], median = summary(mpg)[3], mean = summary(mpg)[4], max = summary(mpg)[6

我注意到这里有很多例子,它们使用
dplyr::mutate
与返回多个输出的函数组合来创建多个列。例如:

tmp <- mtcars %>%
    group_by(cyl) %>%
    summarise(min = summary(mpg)[1],
              median = summary(mpg)[3],
              mean = summary(mpg)[4],
              max = summary(mpg)[6])
tmp%
组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别
总结(最小=总结(mpg)[1],
中位数=汇总(mpg)[3],
平均值=汇总(mpg)[4],
最大值=汇总(mpg)[6])
然而,这种语法意味着在本例中,
summary
函数被调用了4次,这似乎不是特别有效。有哪些方法可以有效地将列表输出分配给
摘要
变异
中的列名列表


例如,从前面的一个问题:,我知道您可以将
摘要的输出指定为一个列表,然后使用
do(data.frame(…)
对其进行拆分,但是这意味着您以后必须添加列名,语法也不那么漂亮。

这解决了您的示例,但也许不是你的主要问题。在您展示的案例中,您可以将其改写为:

tmp <- mtcars %>%
    group_by(cyl) %>%
    summarise_each(funs(min, median, mean, max), mpg)
然而,肯定还有其他情况不能解决这个问题

编辑:

do()
函数可以解决这个问题。e、 g

by_cyl <- group_by(mtcars, cyl) %>%
        do(mod = summary(.)[c(1,4,6),])
按循环%
do(mod=摘要(.)[c(1,4,6),]

我在
dplyr
中找不到一个合适的解决方案,它可以让您以易于记忆的方式分配名称。我发现以下
数据表
解决方案可以接受,如果有点冗长:

data.table(mtcars) %>%
    .[, setattr(as.list(summary(mpg)[c(1,3,4,6)]), 
        "names", c("min", "median", "mean", "max")),
         by = cyl]
这源自,其中:

data.table(mtcars) %>%
    .[, as.list(summary(mpg)[c(1,3,4,6)]), by = cyl]
自动将函数的输出指定为4列。因此,唯一剩下的就是使用
setattr
函数适当地重命名列


请注意,
summary
的输出不是列表,因此必须强制为列表才能工作

我是这样做的。对于我拥有的4500万行数据集,它的运行速度相当快

tmp <- mtcars %>%
  group_by(cyl) %>%
  do(data.frame(t(as.matrix(summary(.$mpg)[c(1, 3, 4, 6)]))))

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

    cyl  Min. Median  Mean  Max.
  <dbl> <dbl>  <dbl> <dbl> <dbl>
1     4  21.4   26.0 26.66  33.9
2     6  17.8   19.7 19.74  21.4
3     8  10.4   15.2 15.10  19.2
tmp%
组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别
do(数据帧(作为矩阵(摘要(.$mpg)[c(1,3,4,6)]))
来源:本地数据帧[3 x 5]
组别:共青团[3]
气缸最小值中值平均值最大值。
1     4  21.4   26.0 26.66  33.9
2     6  17.8   19.7 19.74  21.4
3     8  10.4   15.2 15.10  19.2

罗曼·弗朗索瓦(Romain Francois)的
领带
套装可以非常巧妙地做到这一点

devtools::install_github("romainfrancois/tie")
library('tidyverse')
library('tie')

tmp <- mtcars %>%
  group_by(cyl) %>%
  bow( tie(min, median, mean, max) := summary(mpg)[c(1,3,4,6)] )
devtools::install\u github(“romainfrancois/tie”)
库('tidyverse')
图书馆(tie)
tmp%
组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别
弓(结(最小、中位数、平均值、最大值):=汇总(mpg)[c(1,3,4,6)])
注意使用
:=
而不是
=


tidyverse团队在这里以及本文中引用的其他文章中考虑了使用在摘要中返回向量(而非标量)的函数的问题。

这也可以通过使用
tidyr::nest
purrr::map
来实现。注意,summary返回的输出需要从命名向量转换为data.frame或tibble,我使用下面的
dplyr::bind_rows
来实现这一点,但同样可以使用
data.frame(as.list(summary(.$mpg))


抑制警告(库(tidyverse))
mtcars%>%
组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别组别
嵌套()%>%
摘要(stats=map(数据,~bind_行(摘要(.$mpg)))%>%
unnest(统计)
#>#tibble:3 x 7
#>气缸最小值'1st Qu.'中间值'3rd Qu.'最大值。
#>              
#> 1     4 21.4    22.80     26.0    26.66364 30.40     33.9   
#> 2     6 17.8    18.65     19.7    19.74286 21.00     21.4   
#> 3     8 10.4    14.40     15.2    15.10000 16.25     19.2

由(v0.3.0)于2021-04-19创建,您好,谢谢您,但正如您正确指出的,它并没有解决我的主要问题。@Alex添加的编辑应该解决您要查找的内容。这不起作用,结果会分配给一个column@Alex不,他们被分配到一个列表中,由_cyl$mod。所有结果都在那里,可以访问。另请参阅“在dplyr mutate中返回列表”。
devtools::install_github("romainfrancois/tie")
library('tidyverse')
library('tie')

tmp <- mtcars %>%
  group_by(cyl) %>%
  bow( tie(min, median, mean, max) := summary(mpg)[c(1,3,4,6)] )