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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:31:00