dplyr包group_map调用自定义函数参数传递异常是什么原因?
这是group_map的正常设计,问题出在你对该函数的传参规则理解有误。
核心差异
purrr::map处理split得到的列表时,只会把每个子数据框作为唯一的位置参数传递给自定义函数;但dplyr::group_map默认会给自定义函数传递两个固定位置参数:
- 第一个参数:当前分组的子数据框
- 第二个参数:当前分组的分组键(一行tibble,存储当前分组的分组变量取值)
你额外传入的自定义参数,会按顺序排在这两个固定参数之后传递。
异常现象的原因
你的f1仅定义了3个形参,完全匹配不上group_map的传参逻辑:
- 直接调用
group_map(f1, .keep = TRUE)时:第二个固定参数(分组键)被赋值给了par1,所以输出里par1变成了分组名,par2使用默认值FALSE。 - 手动传
par1 = TRUE时:第二个固定参数(分组键)被赋值给了par2,你传入的TRUE作为第三个参数赋值给par1,所以输出里par1是TRUE,par2是分组名。 - 同时传
par1 = TRUE, par2 = TRUE时:group_map总共传递了4个参数(子数据框、分组键、TRUE、TRUE),但你的f1仅定义了3个形参,多出来的参数没有地方接收,就触发了unused argument报错。
解决方法
方法1:修改自定义函数,预留分组键的参数位置
你可以添加第二个参数接收分组键,不需要使用的话直接忽略即可:
# 新增第二个参数.key接收分组键,也可以写...吞掉所有多余位置参数 f1 = function(df, .key, par1 = FALSE, par2 = FALSE){ paste(par1, par2, df$name[1], mean(df$y)) } # 调用即可得到预期结果 df %>% group_by(name) %>% group_map(f1, par1 = TRUE, par2 = TRUE, .keep = TRUE)
方法2:用匿名函数包装,明确传参逻辑
不想修改原函数的话,可以在group_map里用公式写法的匿名函数,只把子数据框传给f1即可:
# 原函数不用修改 df %>% group_by(name) %>% group_map(~f1(.x, par1 = TRUE, par2 = TRUE), .keep = TRUE)
两种写法的输出都和split+map的结果完全一致。
内容的提问来源于stack exchange,提问作者Marek Fiołka
相关产品推荐
相关产品推荐

