总结一种方式,剩下的另一种方式

Summarizing one way, then another for what's left

iris为例。 按 Species 分组后,我想按其 mean 汇总 Sepal.Length,然后按 last 汇总所有剩余列; (不单独调出其余列。)想要结果

# A tibble: 3 x 5
Species    Sepal.Length    Sepal.Width Petal.Length Petal.Width
<fct>             <dbl>          <dbl>        <dbl>       <dbl>
1 setosa           5.01            3.3          1.4         0.2
2 versicolor       5.94            2.8          4.1         1.3
3 virginica        6.59            3            5.1         1.8

运行没有错误:

library(tidyverse)
iris %>% 
  as_tibble %>% 
  group_by(Species) %>% 
  summarise_all(~last(.))

但事实并非如此:

iris %>% 
  as_tibble %>% 
  group_by(Species) %>% 
  summarise_all(Sepal.Length = mean(Sepal.Length), ~ last(.))

我试过使用 everything() 并使用 summarise_atsummarise_if,但我没有找到正确的语法来执行此操作。

完成任务,没有找到更优雅的:

inner_join(iris %>% 
              select(Species,Sepal.Length) %>%
              group_by(Species) %>% 
              summarise_all(list(mean)),
           iris %>% 
              select(-Sepal.Length) %>%
              group_by(Species) %>% 
              summarise_all(list(last)),
           by = "Species")

由于summarise_atsummarise_all将相同的函数映射到选定的变量,因此不能在此处使用。

以自动方式对不同列执行不同摘要的一种方法是使用引用和取消引用技术创建 expression

library(dplyr)

cols = names(iris)[2:4]  # select remaining columns 
col_syms = syms(cols)  # create symbols from strings

summary_vars <- lapply(col_syms, function(col) {
  expr(last(!!col))  # expression that should be evaluated in summarise
})
names(summary_vars) = cols  # new column names (set old names)

iris %>%  
  group_by(Species) %>%
  summarise(Sepal.Length = mean(Sepal.Length), !!!summary_vars)  # open expressions

您可以通过将 dplyr 的管道包装到 rlang::qq_show()

中来查看要评估的内容