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

如何在dplyr的filter与summarise中使用动态变量编写R函数?

解决dplyr函数中动态变量的使用问题

我尝试用DRY原则精简R代码,但编写使用dplyr的函数时,没法正确处理动态变量。原代码如下:

calc <- function(df, count_var, sample_var, pct_var) {
  df %>%
    filter_at(vars(count_var, sample_var), all_vars(!is.na(.))) %>%
    group_by(dated, device_category, path) %>%
    summarise(
      .groups = "keep",
      total_good := sum(df[[count_var]], na.rm = TRUE),
      sample_var := sum(df[[sample_var]], na.rm = TRUE),
      pct_var := total_good / df[[sample_var]]
    )
}

lcp <- calc(data, 'lcp_good_count', 'lcp_sample', 'lcp_good_pct')

需要修改代码,让传入的变量名能正确完成过滤和汇总计算。


修正后的代码(兼容字符串参数)

library(dplyr)

calc <- function(df, count_var, sample_var, pct_var) {
  # 将字符串参数转换为dplyr可识别的符号
  count_sym <- rlang::sym(count_var)
  sample_sym <- rlang::sym(sample_var)
  pct_sym <- rlang::sym(pct_var)
  
  df %>%
    # 用across替代已弃用的filter_at,处理动态列的NA过滤
    filter(across(c({{count_var}}, {{sample_var}}), ~!is.na(.x))) %>%
    group_by(dated, device_category, path) %>%
    summarise(
      .groups = "keep",
      total_good := sum(!!count_sym, na.rm = TRUE),
      !!sample_sym := sum(!!sample_sym, na.rm = TRUE),
      !!pct_sym := total_good / !!sample_sym
    )
}

# 调用函数(传入字符串参数)
lcp <- calc(data, 'lcp_good_count', 'lcp_sample', 'lcp_good_pct')

关键修改说明

  • 替换过时的filter_at:filter_at已被dplyr官方弃用,改用filter(across(...))实现多列NA过滤,{{ }}语法可直接兼容字符串或裸变量形式的参数。
  • 动态变量与列名处理:
    • 用rlang::sym()将字符串参数转为符号,配合!!(bang-bang操作符)在dplyr函数中引用动态变量,避免直接使用df[[var]](分组后应基于当前组数据计算,而非原数据框)。
    • 通过!!sym(var) :=的格式实现动态列命名,让传入的参数名直接成为汇总后的列名。
  • 分组求和逻辑:求和时直接使用转换后的符号变量,确保计算的是当前分组内的总和,而非原数据框的全局总和。

可选:支持裸变量的简化版本

如果调用时不想加引号,可以直接用{{ }}处理裸变量:

calc <- function(df, count_var, sample_var, pct_var) {
  df %>%
    filter(across(c({{count_var}}, {{sample_var}}), ~!is.na(.x))) %>%
    group_by(dated, device_category, path) %>%
    summarise(
      .groups = "keep",
      total_good := sum({{count_var}}, na.rm = TRUE),
      {{sample_var}} := sum({{sample_var}}, na.rm = TRUE),
      {{pct_var}} := total_good / {{sample_var}}
    )
}

# 调用时无需加引号
lcp <- calc(data, lcp_good_count, lcp_sample, lcp_good_pct)

内容的提问来源于stack exchange,提问作者purpletonic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:55:12