dplyr按不同函数对多个列汇总(折叠)数据集

dplyr按不同函数对多个列汇总(折叠)数据集,r,group-by,dplyr,summarize,R,Group By,Dplyr,Summarize,我正试图通过不同的summary_在/summary_if函数对dplyr::summary数据集(折叠)进行汇总,以便在输出数据集中具有相同的命名变量。例如: library(tidyverse) data(iris) iris$year <- rep(c(2000,3000),each=25) ## for grouping iris$color <- rep(c("red","green","blue"),each=50) ## character column iris$le

我正试图通过不同的
summary_在
/
summary_if
函数对
dplyr::summary
数据集(折叠)进行汇总,以便在输出数据集中具有相同的命名变量。例如:

library(tidyverse)
data(iris)
iris$year <- rep(c(2000,3000),each=25) ## for grouping
iris$color <- rep(c("red","green","blue"),each=50) ## character column
iris$letter <- as.factor(rep(c("A","B","C"),each=50)) ## factor column
head(iris, 3)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species year color letter
1          5.1         3.5          1.4         0.2  setosa 2000   red      A
2          4.9         3.0          1.4         0.2  setosa 2000   red      A
3          4.7         3.2          1.3         0.2  setosa 2000   red      A
库(tidyverse)
数据(iris)
iris$年%
总结_if(is.factor,list(last))
第一%
按(物种、年份)划分的组别%>%
总结_if(is.character,list(first))
完全%full\u加入(最后一次)%>%full\u加入(第一次)
我在下面找到了类似的方法,但无法找出我在这里尝试过的方法。我不想做我自己的功能,因为我认为这样的东西更干净,通过将所有东西穿过管道并连接:

test <- iris %>%
  #group_by(.vars = vars(Species, year)) %>% #why doesnt this work?
  group_by_at(.vars = vars(Species, year))  %>% #doesnt work 
    {left_join(
    summarise_at(., vars(matches("Width")), list(sum)),
    summarise_at(., vars(matches("Length")), list(max)),
    summarise_if(., is.factor, list(last)),
    summarise_if(., is.character, list(first))
    )
      } #doesnt work
test%
#分组依据(.vars=vars(物种,年份))%>%#为什么不起作用?
分组时间:(.vars=vars(物种,年份))%>%不起作用
{left_join(
总结(、变量(匹配(“宽度”)、列表(总和)),
总结(、变量(匹配项(“长度”)、列表(最大值)),
如果(、是系数、列表(最后一个)),则总结,
总结_if(,is.字符,列表(第一))
)
}#不起作用
这行不通,有什么建议或其他方法吗

有益的:

默认情况下,
dplyr::left_join()
函数只接受两个数据帧。如果要将此函数用于两个以上的数据帧,可以使用
Reduce
函数(base R函数)对其进行迭代:


虹膜%>%
按(物种、年份)划分的组别%>%
{
减少(
函数(x,y)左联合(x,y),
名单(
在(、变量(匹配(“宽度”)、基数::总和)汇总,
在(、变量(匹配项(“长度”)、基数::最大值)汇总,
如果(,is.factor,dplyr::last),则总结,
总结_if(,is.character,dplyr::first)
))
}
#种年萼片。宽花瓣。宽萼片。长花瓣。长字母颜色
#                                          
#1 setosa 2000 87 6.2 5.8 1.9 A红色
#2 setosa 3000 84.4 6.1 5.5 1.9 A红色
#3 versicolor 2000 69.4 33.6 7 4.9 B绿色
#4花色3000 69.1 32.7 6.8 5.1 B绿色
#5维吉尼亚2000 73.2 51.1 7.7 6.9 C蓝色
#6维吉尼亚3000 75.5 50.2 7.9 6.4 C蓝色

此外,请注意,我必须使用
从其包中调用函数,以避免名称与以前创建的数据帧重叠。

Robbing@Ulises idea并使用
Purr::reduce
而不是
reduce
是一种替代方法:

iris %>%
  group_by(Species, year) %>%
  list(
    summarise_at(., vars(matches("Width")), base::sum),
    summarise_at(., vars(matches("Length")), base::max),
    summarise_if(., is.factor, dplyr::last),
    summarise_if(., is.character, dplyr::first)
  ) %>%
  .[c(2:5)] %>%
  reduce(left_join)
带花括号的解决方案以抑制第一个参数:

iris %>%
  group_by(Species, year) %>%
  {
  list(
    summarise_at(., vars(matches("Width")), base::sum),
    summarise_at(., vars(matches("Length")), base::max),
    summarise_if(., is.factor, dplyr::last),
    summarise_if(., is.character, dplyr::first)
  )
  } %>%
  reduce(left_join)

您想要宽度列的总和、长度列的最大值、最后一个字母和第一个颜色?使用摘要功能,例如
summary(最小(分隔宽度)、最大(分隔长度))
第二种方法只有在有两条摘要语句时才有效,因为full\u join只能连接两个数据帧
left\u join
编辑@Vikrant如果我有一个包含许多变量的大型数据集,那就不够灵活了。如果
解决了这个问题,请使用
总结,谢谢。能把它简化得更简单吗?我不知道purr也能帮上忙。下面的答案看起来不错,@user63230对于较大的数据集,这可能会非常慢。请参阅其他解决方法
#   Species     year Sepal.Width Petal.Width Sepal.Length Petal.Length letter color
#   <fct>      <dbl>       <dbl>       <dbl>        <dbl>        <dbl> <fct>  <chr>
# 1 setosa      2000        87           6.2          5.8          1.9 A      red  
# 2 setosa      3000        84.4         6.1          5.5          1.9 A      red  
# 3 versicolor  2000        69.4        33.6          7            4.9 B      green
# 4 versicolor  3000        69.1        32.7          6.8          5.1 B      green
# 5 virginica   2000        73.2        51.1          7.7          6.9 C      blue 
# 6 virginica   3000        75.5        50.2          7.9          6.4 C      blue 
iris %>%
  group_by(Species, year) %>%
  list(
    summarise_at(., vars(matches("Width")), base::sum),
    summarise_at(., vars(matches("Length")), base::max),
    summarise_if(., is.factor, dplyr::last),
    summarise_if(., is.character, dplyr::first)
  ) %>%
  .[c(2:5)] %>%
  reduce(left_join)
iris %>%
  group_by(Species, year) %>%
  {
  list(
    summarise_at(., vars(matches("Width")), base::sum),
    summarise_at(., vars(matches("Length")), base::max),
    summarise_if(., is.factor, dplyr::last),
    summarise_if(., is.character, dplyr::first)
  )
  } %>%
  reduce(left_join)