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

如何编写包装函数用purrr::map遍历列名调用tidyeval函数?

解决方案

1. 优化inner_function的列名获取写法

可以用rlang::as_label({{x}})替代繁琐的rlang::as_name(rlang::enquo(x)),语法更简洁,效果完全一致:

inner_function <- function(df, x) {
  df %>% 
    distinct({{x}}) %>% 
    rename(level = {{x}}) %>% 
    mutate(term = rlang::as_label({{x}}))
}

2. 编写包装函数实现多列遍历

要通过purrr::map()遍历多列,核心是确保传递给inner_function的列名能被tidyeval正确捕获,以下是三种可行方案:

方案一:基于符号向量遍历

先将目标列名转换为符号列表,再传递给map():

wrap_function_sym <- function(df, cols) {
  col_syms <- rlang::syms(cols)
  purrr::map_dfr(col_syms, ~inner_function(df, !!.x))
}

# 使用示例:传入列名字符串向量
mpg %>% wrap_function_sym(c("drv", "class", "fl"))

方案二:兼容字符串输入的遍历

调整inner_function使其同时支持符号和字符串输入,再直接遍历字符串列名:

# 调整后的inner_function
inner_function <- function(df, x) {
  x <- rlang::ensym(x) # 将输入统一转为符号,兼容字符串/符号两种输入
  df %>% 
    distinct({{x}}) %>% 
    rename(level = {{x}}) %>% 
    mutate(term = rlang::as_label(x))
}

# 包装函数
wrap_function_str <- function(df, cols) {
  purrr::map_dfr(cols, ~inner_function(df, .x))
}

# 使用示例
mpg %>% wrap_function_str(c("drv", "class", "fl"))

方案三:用imap直接绑定列名

如果不需要依赖tidyeval捕获列名,也可以用imap直接将遍历的列名作为term值:

wrap_function_imap <- function(df, cols) {
  purrr::imap_dfr(cols, function(col, name) {
    df %>% 
      distinct(.data[[col]]) %>% 
      rename(level = .data[[col]]) %>% 
      mutate(term = name)
  })
}

# 使用示例
mpg %>% wrap_function_imap(c("drv", "class", "fl"))

运行结果

以上方案都会返回合并后的结果,包含所有目标列的唯一值及对应列名,示例输出:

#> # A tibble: 19 × 2
#>   level term  
#>   <chr> <chr> 
#> 1 f     drv   
#> 2 4     drv   
#> 3 r     drv   
#> 4 2seater class
#> 5 compact class
#> # ℹ 14 more rows

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:37:00