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

如何结合dplyr的group_by、summarise、across实现多函数输出?

按分组批量计算多列与指定列的相关性(tidyverse高效方案)

测试数据

tTest = tibble(Cells = rep(c("C1", "C2", "C3"), times = 3), 
               Gene = rep(c("G1", "G2", "G3"), each = 3), 
               Experiment_score = 1:9, 
               Pattern1 = 1:9, 
               Pattern2 = -(1:9), 
               Pattern3 = 9:1) %>%
        group_by(Gene)

需求

按Gene分组,计算Experiment_score与所有以Pattern开头的列的相关性,输出相关系数和对应的p值。

最初尝试的问题

尝试用across结合返回列表的包装函数corList,但返回嵌套的列表列,结果不符合预期:

# 返回列表的包装函数
corList = function(x, y) {
    result = cor.test(x, y)
    return(list(stat = result$estimate, pval = result$p.value))
}

# 执行后得到异常的嵌套列结果
tTest %>% summarise(across(starts_with("Pattern"), ~ corList(Experiment_score, .x), .names = "{.col}_corr_{.fn}"))

高效解决方案(无需转长表)

核心是让相关性包装函数返回tibble而非列表/向量,这样across可以直接将结果展开为多列,避免转长表的性能损耗:

1. 定义返回tibble的相关性函数

cor_tibble = function(x, y) {
  res = cor.test(x, y)
  tibble(corr = res$estimate, corr_pval = res$p.value)
}

2. 结合across批量计算

tTest %>%
  summarise(across(starts_with("Pattern"), 
                   ~ cor_tibble(Experiment_score, .x),
                   .names = "{.col}_{.value}"))

执行后会得到宽表格式的结果,每个Pattern列对应两列输出:例如Pattern1_corr(相关系数)、Pattern1_corr_pval(p值),完全匹配需求,且无需转长表,在百万行+数十个Pattern列的场景下,内存占用和计算效率远优于转长表方法。

原转长表的不完善方案

以下是最初的解决方案,虽然能得到正确结果,但数据量大时会因pivot_longer导致数据膨胀,严重影响处理效率:

# 返回向量的包装函数
corVect = function(x, y) {
    result = cor.test(x, y)
    return(c(stat = result$estimate, pval = result$p.value))
}

# 转长表计算后再转回宽表
tTest %>% pivot_longer(starts_with("Pattern"), names_to = "Pattern", values_to = "Strength") %>%
      group_by(Gene, Pattern) %>%
      summarise(CorrVal = corVect(Experiment_score, Strength)) %>% 
      mutate(CorrType = c("corr", "corr_pval")) %>%
      pivot_wider(id_cols = c(Gene, Pattern), names_from = CorrType, values_from = CorrVal)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:30:50