在dplyr::summarize中实现自定义聚合并自动保留所有列
自动保留所有列的字符串拆分实现
我有如下结构的DataFrame,核心需求是拆分包含&符号的字符串,将&两侧的值各占一行,生成行数翻倍的新DataFrame。目前通过dplyr::summarize结合自定义函数可以实现,但必须手动指定并重复(rep)所有其他列(比如示例中的val1和val2)才能保留到结果里。我需要找到无需手动指定,就能自动保留所有其他列值的实现方式。注意:我不寻求拆分字符串的其他方法,只关注生成新DataFrame时自动保留所有其他列的实现逻辑。
数据创建代码
# 创建数据 library(dplyr) df <- data.frame(string = paste0(LETTERS,"&",rev(letters)),val1 = 1:26,val2 = 26:1)
需手动指定列的可行版本
这个版本能生成正确输出,但新增列时必须手动修改函数,扩展性差:
cleaner <- function(string,val1,val2){ split <- strsplit(string,"&") # 提取&左侧的所有值 string1 <- sapply(split,"[[",1) # 提取&右侧的所有值 string2 <- sapply(split,"[[",2) # 组装结果,手动保留其他列 tibble(string = c(string1,string2), val1 = rep(val1,2), val2 = rep(val2,2)) } summarize(df,cleaner(string,val1,val2))
期望的代码形式(待实现)
希望通过...接收所有其他列,无需手动指定列名:
cleaner <- function(string,...){ split <- strsplit(string,"&") string1 <- sapply(split,"[[",1) string2 <- sapply(split,"[[",2) # 组装结果,自动保留其他列 tibble(string = c(string1,string2),...) } summarize(df,cleaner(string,...))
最终实现方案
通过对...参数做批量重复处理,实现自动保留所有其他列:
cleaner <- function(string, ...) { split <- strsplit(string, "&") # 生成拆分后的字符串向量 string_vec <- c(sapply(split, "[[", 1), sapply(split, "[[", 2)) # 对所有传入的额外列执行重复两次的操作,再合并为数据框 extra_cols <- list(...) %>% purrr::map(~ rep(.x, 2)) %>% dplyr::bind_cols() # 组装最终结果 dplyr::tibble(string = string_vec, extra_cols) } # 调用方式:自动传入除string外的所有列 df %>% dplyr::summarize(cleaner(string, dplyr::across(-string)))
说明
- 函数内部通过
list(...)接收所有额外列,再用purrr::map对每个列执行rep(.,2),保证每个列的行数和拆分后的string列一致 - 调用时使用
dplyr::across(-string)自动选中所有非string列,无需手动列名,新增列时无需修改调用代码
内容的提问来源于stack exchange,提问作者Aaron Graybill
相关产品推荐
相关产品推荐

