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

如何在R函数中正确引用新创建变量并传递给辅助函数?

Backtrace:

  1. global treemap_index1(df, region, district, sales)
  2. scales (local) mydollars("{{agg_number}}2")
  3. scales::dollar(...)
  4. scales::number(...)
  5. scales:::scale_cut(...)
  6. base::cut(...)
    Run rlang::last_trace() to see the full context.
如果将有问题的代码替换为如下内容,函数可以正常运行:
```r
treemap_index2 <- function(df, category1, category2, agg_number){
  
  df_out <- df %>% 
    mutate("{{category2}}.index" := paste({{category2}}, mydollars({{agg_number}}), sep = "\n")) %>% 
    group_by({{category1}}) %>%
    mutate("{{agg_number}}2" := sum({{agg_number}}),
           "{{category1}}.index" := paste({{category1}}, 
                                          "Test String", # 临时替换的代码
                                          sep = "\n")) %>%
    print()
  
  return(df_out)
  
}
treemap_index2(df, region, district, sales)

# A tibble: 6 × 6
# Groups:   region [2]
  region district      sales district.index       sales2 region.index        
  <chr>  <chr>         <dbl> <chr>                 <dbl> <chr>               
1 North  Dist-1         2000 "Dist-1\n$2 K"   1800003600 "North\nTest String"
2 South  Dist-2    300001600 "Dist-2\n$300 M" 2700002400 "South\nTest String"
3 North  Dist-3    600001200 "Dist-3\n$600 M" 1800003600 "North\nTest String"
4 South  Dist-4    900000800 "Dist-4\n$900 M" 2700002400 "South\nTest String"
5 North  Dist-5   1200000400 "Dist-5\n$1.2 B" 1800003600 "North\nTest String"
6 South  Dist-6   1500000000 "Dist-6\n$1.5 B" 2700002400 "South\nTest String"
解决方案

报错的核心原因是"{{agg_number}}2"被当作字符串传递给了mydollars,而不是引用数据框中刚创建的数值变量。要解决这个问题,需要先动态生成新变量的名称,再正确引用它:

修改后的函数

treemap_index1 <- function(df, category1, category2, agg_number){
  # 将参数转换为字符串,拼接得到新列名
  agg_col <- rlang::as_name(enquo(agg_number))
  agg_col2 <- paste0(agg_col, "2")
  
  df_out <- df %>% 
    mutate("{{category2}}.index" := paste({{category2}}, mydollars({{agg_number}}), sep = "\n")) %>% 
    group_by({{category1}}) %>%
    mutate(!!agg_col2 := sum({{agg_number}}),
           "{{category1}}.index" := paste({{category1}}, 
                                         mydollars(.data[[agg_col2]]), # 使用.data代词引用动态列
                                         sep = "\n"))
  
  return(df_out)
}

# 测试函数
treemap_index1(df, region, district, sales)

关键说明

  1. 动态生成列名:用rlang::as_name(enquo(agg_number))把输入的参数转换为字符串,再拼接"2"得到聚合后的列名agg_col2。
  2. 引用动态列:使用.data[[agg_col2]]来访问新创建的列,这是tidyverse中推荐的动态引用列的方式,避免字符串直接传递导致的类型错误。
  3. 创建动态列:用!!agg_col2 := sum({{agg_number}})来创建带后缀的聚合列,!!用于将字符串转换为变量名。

代码优化建议

  • 去掉函数内的print(),让返回的数据框由用户自行决定是否打印,保持函数的纯粹性。
  • 用glue::glue替代paste,让字符串拼接更直观:
    mutate("{{category2}}.index" := glue::glue("{category2}\n{mydollars(agg_number)}"))
    
  • 可以添加参数来自定义后缀(比如把"2"作为可选参数),进一步提升函数的复用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:55:37