在purrr::map_df中调用R函数时额外参数未生效问题排查
问题描述
我编写了一个可执行多种统计检验(默认是wilcoxon秩和检验)的函数,返回每行对应一个检验结果的数据框。尝试为统计检验添加额外参数(如alternative)时,发现参数未生效。
测试代码
library(rstatix) library(tidyverse) calculate_pval <- function(df, xvar, yvars, test = wilcox_test, ...){ stat_test <- yvars %>% map(rlang::sym) %>% map(\(y) rlang::inject(!! y ~ !! rlang::ensym(xvar))) %>% map_df(~ test(.x, ..., data = df)) return (stat_test) }
使用ToothGrowth数据集测试:
data("ToothGrowth") df <- ToothGrowth
直接调用wilcox_test时,添加alternative = "greater"会改变p值,但通过calculate_pval函数调用时,该参数无效果。请问是我对ellipsis(...)的使用有误,还是在map_df内的实现方式存在固有问题?
问题原因与解决方法
问题出在函数参数的传递顺序上,而非...或map_df的使用本身。
rstatix包中的检验函数(如wilcox_test)的标准调用语法是:
wilcox_test(data, formula, ...)
即data参数要放在formula之前,但你在map_df里的调用是test(.x, ..., data = df),这会把.x(公式)作为第一个参数传递,然后是...里的参数,最后指定data = df。这种情况下,...中的参数会被错误地绑定到公式之后的位置,但rstatix函数会优先按位置匹配参数,导致alternative这类参数没有被正确识别。
修正后的代码
只需要调整test调用时的参数顺序,把data = df放在最前面,再传递公式和...参数:
calculate_pval <- function(df, xvar, yvars, test = wilcox_test, ...){ stat_test <- yvars %>% map(rlang::sym) %>% map(\(y) rlang::inject(!! y ~ !! rlang::ensym(xvar))) %>% map_df(~ test(data = df, .x, ...)) # 调整参数顺序:先传data,再传公式,最后是... return(stat_test) }
验证测试
运行以下代码对比结果,可确认参数已生效:
# 直接调用wilcox_test direct_result <- wilcox_test(data = df, len ~ supp, alternative = "greater") # 通过函数调用 func_result <- calculate_pval(df, xvar = "supp", yvars = "len", alternative = "greater") # 查看两者p值是否一致 direct_result$p func_result$p
内容的提问来源于stack exchange,提问作者user23485480
相关产品推荐
相关产品推荐

