如何在dplyr中按指定列分组,动态为列赋值组内最大值?
解决动态批量替换分组列的组内最大值问题
嘿,我完全理解你的需求——按静态列x分组后,把指定的列批量替换成各自的组内最大值,而且不想硬写列名,要动态指定对吧?之前用mutate!!或者旧的mutate_加lazyeval踩坑了?其实现在用dplyr的新语法就能轻松搞定,而且完美支持批量处理,不用循环。
首先先把你的示例数据整理成可运行的格式:
library(dplyr) # 示例数据 my.events <- tibble( x = c(1, 2, 3, 4, 5), title = c("2016-11-24", "2016-11-25", "2016-11-26", "2016-11-26", "2016-11-27"), typethx = c(1, 2, 3, 0, 0), typesea = c(0, 0, 0, 1, 2) )
1. 动态指定单个列的处理
如果你已经定义了单个列名的变量,比如name <- "typethx",可以用all_of()配合across()来实现动态替换:
name <- "typethx" my.events <- my.events %>% group_by(x) %>% mutate(across(all_of(name), ~max(.x))) %>% # 对指定列应用组内最大值 ungroup()
这里all_of()的作用是把字符类型的列名转换成dplyr能识别的列引用,across()则是用来对指定列应用函数,~max(.x)就是取当前组内该列的最大值。
2. 批量处理多个列(你的核心额外需求)
对于dummy.cols <- c('typethx', 'typesea')这样的列名向量,直接把它传给all_of()就行,完全不用循环:
dummy.cols <- c('typethx', 'typesea') my.events <- my.events %>% group_by(x) %>% mutate(across(all_of(dummy.cols), ~max(.x))) %>% # 批量处理所有指定列 ungroup()
举个更直观的例子,如果我们修改示例数据,让x有重复分组:
# 修改后的示例数据,x=3有两个行 my.events <- tibble( x = c(1, 2, 3, 3, 5), title = c("2016-11-24", "2016-11-25", "2016-11-26", "2016-11-26", "2016-11-27"), typethx = c(1, 2, 3, 0, 0), typesea = c(0, 0, 0, 1, 2) )
运行上面的批量处理代码后,x=3的两行中,typethx都会变成组内最大值3,typesea都会变成组内最大值1,完全符合你的需求。
如果你用的是旧版本dplyr(低于1.0.0)
如果你的dplyr版本比较旧,还没有across(),可以用mutate_at()来实现:
# 旧版本批量处理写法 dummy.cols <- c('typethx', 'typesea') my.events <- my.events %>% group_by(x) %>% mutate_at(vars(all_of(dummy.cols)), funs(max(.))) %>% ungroup()
最后验证处理后的结果:
print(my.events)
内容的提问来源于stack exchange,提问作者Scratch'N'Purr
相关产品推荐
相关产品推荐

