You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用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))

代码说明

  1. ensyms():接收用户传入的符号(比如c(min, hour)),将其转换为rlang的符号列表,方便后续在dplyr函数中使用。
  2. !!!(非拼接操作符):把符号列表“展开”传递给group_by(),效果等同于手动写group_by(min, hour, country)。
  3. .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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:09:51