如何利用tidyselect让rollup函数支持接收类似pivot_longer的符号数组?
解决方案
要支持符号向量输入,需要用到tidyverse的**整洁求值(tidyeval)**语法,核心是用ensyms()把符号参数转换成符号列表,再传递给group_by()。修改后的函数如下:
rollup <- function(.data, time_dims, loc_dims) { # 将符号参数转换为符号列表 time_syms <- ensyms(time_dims) loc_syms <- ensyms(loc_dims) .data %>% group_by(!!!time_syms, !!!loc_syms) %>% summarise(y = mean(y), .groups = "drop_last") # 可选:控制分组保留行为 }
调用示例
现在可以直接传递符号向量了:
rollup(d, time_dims = c(min, hour), loc_dims = c(country))
代码说明
ensyms():接收用户传入的符号(比如c(min, hour)),将其转换为rlang的符号列表,方便后续在dplyr函数中使用。!!!(非拼接操作符):把符号列表“展开”传递给group_by(),效果等同于手动写group_by(min, hour, country)。.groups参数:可选,用来控制summarise()后的分组保留行为,默认是"drop_last",你可以根据需求改成"drop"(完全取消分组)或其他有效值。
兼容字符与符号输入的版本
如果需要同时支持字符向量和符号向量输入,可以在函数中增加参数类型判断,自动处理两种情况:
rollup <- function(.data, time_dims, loc_dims) { # 处理时间维度参数:字符转符号,否则直接取符号 time_syms <- if (is.character(time_dims)) { syms(time_dims) } else { ensyms(time_dims) } # 处理位置维度参数 loc_syms <- if (is.character(loc_dims)) { syms(loc_dims) } else { ensyms(loc_dims) } .data %>% group_by(!!!time_syms, !!!loc_syms) %>% summarise(y = mean(y), .groups = "drop_last") }
这样修改后,不管是传入c('min', 'hour')还是c(min, hour),函数都能正常运行。
内容的提问来源于stack exchange,提问作者Demetri Pananos
相关产品推荐
相关产品推荐

