如何在R中泛化自定义函数以传递多参数调用sjstats的weighted_mannwhitney?
问题描述
我希望在自定义函数中调用sjstats包的weighted_mannwhitney函数,该函数参数为:
weighted_mannwhitney(data, x, grp, weights, ...)
简单调用示例:
weighted_mannwhitney(c12hour ~ c161sex + weight, efc)
我已编写了一个仅能接收data参数的自定义函数own_funk,现在需要扩展它,让它可以接收data、x(支持多变量)、grp、weights等参数,传递给内部调用的weighted_mannwhitney,以此适配不同数据集。
当前可运行的函数:
library(sjstats) library(tidyverse) data(efc) efc$weight <- abs(rnorm(nrow(efc), 1, .3)) own_funk <- function(data, ...) { res <- data %>% summarise( across( c(c12hour,e17age), ~sjstats:::weighted_mannwhitney.formula(.x ~ c161sex + weight, data)$p.value[[1]] ) ) %>% tibble::rownames_to_column() %>% pivot_longer(-rowname) %>% pivot_wider(names_from=rowname, values_from=value) %>% rename("Outcome" = 1, "P-value" = 2) %>% as.data.frame() return(res) }
当前调用方式:own_funk(efc)
期望的调用方式:
own_funk(data = efc, x = c(c12hour,e17age), grp = c161sex, weights = weight)
解决方案
使用tidyverse的非标准求值语法实现参数泛化,修改后的函数如下:
library(sjstats) library(tidyverse) library(glue) # 用于动态拼接公式,可替换为paste data(efc) efc$weight <- abs(rnorm(nrow(efc), 1, .3)) own_funk <- function(data, x, grp, weights) { # 将多变量x转换为符号列表,支持批量处理 x_vars <- rlang::ensyms(x) res <- data %>% summarise( across( all_of(x_vars), ~{ # 动态构建weighted_mannwhitney所需的公式 formula_str <- glue("{rlang::as_name(.)} ~ {rlang::as_name({{grp}})} + {rlang::as_name({{weights}})}") sjstats::weighted_mannwhitney(formula(formula_str), data = data)$p.value[[1]] } ) ) %>% tibble::rownames_to_column() %>% pivot_longer(-rowname) %>% pivot_wider(names_from = rowname, values_from = value) %>% rename("Outcome" = 1, "P-value" = 2) %>% as.data.frame() return(res) }
调用示例
# 按期望方式调用函数 own_funk(data = efc, x = c(c12hour, e17age), grp = c161sex, weights = weight)
核心要点
- 多变量处理:用
rlang::ensyms(x)将输入的多个列名转为符号,结合across(all_of(x_vars))实现批量遍历。 - 动态公式构建:通过
glue拼接公式字符串,再转为公式对象,适配weighted_mannwhitney的公式调用方式;若不想依赖glue,可替换为paste(rlang::as_name(.), "~", rlang::as_name({{grp}}), "+", rlang::as_name({{weights}}))。 - 非标准求值适配:用
{{}}(curly-curly语法)捕获参数中的列名,转换为字符串用于公式拼接,解决自定义函数中列名传递的问题。
内容的提问来源于stack exchange,提问作者microbe
相关产品推荐
相关产品推荐

