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

如何在dplyr::across()中使用返回多值的自定义函数

dplyr::across()单次遍历计算多统计量的实现方案

核心实现思路

across默认会自动展开返回值为命名向量的函数输出,只要自定义函数返回带名称的一维向量,即可直接生成扁平化的独立列,无需额外拆包操作,每列仅遍历一次,完全避免重复计算。

方案1:返回命名向量(最优解)

该方案无需额外依赖包,输出和常规多匿名函数写法完全一致:

# 自定义统计函数,返回命名向量
calc_multi_stats <- function(x) {
  c(
    mean = mean(x, na.rm = TRUE),
    sd = sd(x, na.rm = TRUE),
    median = median(x, na.rm = TRUE),
    missing = sum(is.na(x))
  )
}

# 调用across批量处理
library(dplyr)
result <- mtcars %>% 
  summarise(
    across(c(mpg, disp, hp, drat, wt), calc_multi_stats, .names = "{.col}_{.fn}")
  )

输出列名为mpg_mean、mpg_sd、disp_mean等,和常规传入list(mean = ~mean(.x), sd = ~sd(.x))的输出格式完全一致,无嵌套结构。

方案2:返回数据框时用unpack拆包

如果你的自定义逻辑必须返回数据框结构(例如返回多组关联的分类统计结果),不要使用unnest()处理这类场景——unnest()是针对行维度的展开操作,tidyr::unpack()才是针对列维度嵌套结构的拆包函数:

# 返回数据框的自定义函数
calc_stats_df <- function(x) {
  tibble(
    mean = mean(x, na.rm = TRUE),
    sd = sd(x, na.rm = TRUE),
    range = max(x, na.rm = TRUE) - min(x, na.rm = TRUE)
  )
}

# 调用后拆包
library(tidyr)
result <- mtcars %>% 
  summarise(across(c(mpg, disp, hp), calc_stats_df)) %>% 
  unpack(where(is.data.frame), names_sep = "_")

names_sep = "_"参数会自动生成{原列名}_{统计量名}格式的列名,和常规across输出规则对齐。

命名规则自定义

如果需要调整列名格式,直接修改across的.names参数即可,和常规多函数写法的配置完全通用,例如:

# 生成 统计量名_列名 格式的列名
result <- mtcars %>% 
  summarise(across(c(mpg, hp), calc_multi_stats, .names = "{.fn}_{.col}"))

内容的提问来源于stack exchange,提问作者Dan Chaltiel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:39:02