R 聚合动态添加的列,每个列都有一个单独的函数

标签 r aggregate

我有一个像这样的数据框:

id  v    t1   t2  t3    t4   date1        list1

1   1.0  1.4   2   0.45   3    2020-09-03   val1
1   1.0  1.6   3   0.55  3.7  2020-09-05   val2

如何通过对每个列应用不同的聚合函数来按 id、v 进行分组并聚合列 t1、t2、t3、t4、date1、list1他们。更具体地说

t1 -> mean
t2 -> max
t3 -> mean
t4 -> max
date -> max
list1 -> join as in python's ','.join

因此聚合后的框架如下所示:

id  v    t1   t2  t3    t4   date1        list1

1   1.0  1.5   3   0.5   3.7  2020-09-05   val1, val2

还有一件事是,这些列可以根据 R Shiny 框架中的用户选择动态添加,这意味着我打算聚合的所有这些列都在数据框中,但其中一些可能不需要聚合,例如用户只能选择 t1, date1 而不能选择其余的。因此,我的聚合参数取决于所选的列,并且我确实可以从用户选择中获取列名称。因此,如果我问如何构建动态聚合查询,这可能是有意义的。

在 python 中,我可以根据用户选择的列动态构建一个类似于上面的字典,并使用类似 pd.agg(**dict)

如何在 R 中执行此操作?我尝试查看 dplyr::summarise 和 data.table 但我似乎无法立即聚合所有这些。感谢您的帮助。

最佳答案

我们可以使用across在列 block 上应用函数

library(dplyr)
df1 %>% 
   group_by(id, v) %>% 
   summarise(across(c(t1, t3), mean),
             across(c(t2, t4, date1), max), 
             list1 = toString(list1), .groups = 'drop')

-输出

# A tibble: 1 x 8
#     id     v    t1    t3    t2    t4 date1      list1     
#  <int> <dbl> <dbl> <dbl> <int> <dbl> <chr>      <chr>     
#1     1     1   1.5   0.5     3   3.7 2020-09-05 val1, val2

如果函数、列名都是用户输入

nm1 <- c("t1", "t3")
nm2 <- c("t2", "t4", "date1")
nm3 <- c("list1")

f1 <- "mean"
f2 <- "max"
f3 <- "toString"

df1 %>%
    group_by(id, v) %>%
    summarise(across(all_of(nm1), ~ match.fun(f1)(.)),
              across(all_of(nm2), ~ match.fun(f2)(.)),
              !! nm3 := match.fun(f3)(!! rlang::sym(nm3)), .groups = 'drop')

-输出

# A tibble: 1 x 8
#     id     v    t1    t3    t2    t4 date1      list1     
#  <int> <dbl> <dbl> <dbl> <int> <dbl> <date>     <chr>     
#1     1     1   1.5   0.5     3   3.7 2020-09-05 val1, val2

它也可以作为表达式传递并求值

expr1 <- glue::glue('across(c({toString(nm1)}), {f1});',
              'across(c({toString(nm2)}),  {f2});',
          'across(c({toString(nm3)}),  {f3})')
df1 %>% 
     group_by(id, v) %>%
     summarise(!!! rlang::parse_exprs(expr1), .groups = 'drop')

-输出

# A tibble: 1 x 8
#     id     v    t1    t3    t2    t4 date1      list1     
#  <int> <dbl> <dbl> <dbl> <int> <dbl> <date>     <chr>     
#1     1     1   1.5   0.5     3   3.7 2020-09-05 val1, val2

数据

df1 <- structure(list(id = c(1L, 1L), v = c(1, 1), t1 = c(1.4, 1.6), 
    t2 = 2:3, t3 = c(0.45, 0.55), t4 = c(3, 3.7), date1 = structure(c(18508, 
    18510), class = "Date"), list1 = c("val1", "val2")), row.names = c(NA, 
-2L), class = "data.frame")

关于R 聚合动态添加的列,每个列都有一个单独的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64849927/

相关文章:

r - 有条件地从两个数据文件中添加某些数据列

r - 使用 dplyr 将行名称保留为 id

r - 在R中按月汇总行

r - 按多列分组并对其他多列求和

r - JDBC 创建表并在 amazon redshift 中插入时出错

r - 使用相同的分组因子多次计算组均值

r - 如何使用正态分布来计算一名球员在一场比赛中得分高于另一名球员的概率?

折叠/分组列表以聚合最大/最小值的 Pythonic 方式

python - 删除 agg 创建的标签( ['sum' ,'count' ])

c++ - 我可以在 "too few initializers"上导致编译错误吗?