如何在purrr的map中调用带可变参数的自定义函数
purrr map 调用自定义函数时的灵活参数配置方法
核心调用逻辑
purrr 系列的 map 函数默认支持自动参数转发:遍历的列表/向量元素会自动作为自定义函数的第一个位置参数传入,.f参数之后显式声明的具名参数,会自动匹配自定义函数的同名形参,直接覆盖函数的默认值。
针对你需求的直接实现
首先修正原自定义函数的两处潜在兼容/语法问题,避免实际调用时报错:
- 原函数形参
data = data的写法存在逻辑缺陷:R 函数形参的默认值会在函数定义的作用域内查找对象,此时没有预先定义的data对象,会触发解析报错,正确写法是直接声明data作为必传入参,不需要设置无意义的默认值; - dplyr 新版中使用字符串传入
select的列名时,需要搭配all_of()完成列名匹配,否则会触发非标准求值报错。
修正后的函数定义如下:
library(purrr) library(dplyr) user_fun <- function(data, filter_col = "test") { data %>% select(all_of(filter_col)) }
假设你需要批量遍历的列表对象为my_list,每个元素为独立的数据框,仅需在 map 调用时直接覆写filter_col参数值即可,完全不需要额外包装:
# 定义测试用列表 my_list <- list( tibble(test = 1:3, test_22 = c("a", "b", "c")), tibble(test = 4:6, test_22 = c("d", "e", "f")) ) # map 调用时覆写 filter_col 默认值为 "test_22" map(.x = my_list, .f = user_fun, filter_col = "test_22")
常见场景的扩展用法
- 当需要为每个列表元素传入不同的
filter_col值时,可改用map2实现双维度遍历:把需要传入的列名组成向量作为第二个遍历维度,逐值匹配传入自定义函数# 为每个列表元素指定专属筛选列 col_target <- c("test", "test_22") map2(.x = my_list, .y = col_target, .f = user_fun) - 当参数逻辑复杂、需要临时调整入参顺序时,可使用 purrr 的公式简写语法写匿名函数,显式绑定参数:
map(my_list, ~user_fun(data = .x, filter_col = "test_22"))
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

