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

如何对R语言DataFrame分组成对列批量执行normalizeBetweenArrays归一化?

批量成对列归一化解决方案

问题背景

我有一个大型R语言DataFrame:

df <- data.frame(S.1_Dxx = runif(100, min = 1, max = 3.5)
                 ,S.1_Px1 = runif(100, min = 0.5, max = 3)
                 ,S.2_Dxhfah = runif(100, min = 0.7, max = 2)
                 ,S.2_Pxhgm = runif(100, min = 0.4, max = 1.4)
                 ,S._Dxhgm = runif(100, min = 1, max = 2.5)
                 ,S._Pxhgm = runif(100, min = 0.4, max = 1.4)
)

列名均以S.开头,后跟0-6位数字与_,该前缀(从S到_)可唯一标识需要归一化的列对。我能手动对单组列执行归一化:

library(limma)

normS1 <- df %>% 
  select(starts_with("S.1_")) %>%
  as.matrix() %>% 
  normalizeBetweenArrays(method = "scale") %>% 
  as.data.frame()

但我希望对所有列对执行该归一化操作。我尝试了以下步骤但遇到瓶颈:

multiNormDf <- df %>% 
  pivot_longer(everything(), names_to = "sample", values_to = "intensity") %>% 
  mutate(sampleGroup = word(sample, start = 1, sep = "_")) %>% 
  group_by(sampleGroup) 

如何确保在sampleGroup内将两个samples视为独立样本?是否应将DataFrame拆分为小数据集处理后再合并?我知晓成对列归一化非常规操作,但当前场景下这是最优选择。注:已将归一化方法从vsn改为normalizeBetweenArrays。

解决方案

方法1:拆分-处理-合并(直观易理解)

核心思路是按列前缀分组,拆分出每个组的子DataFrame,分别归一化后再合并回原结构:

  1. 提取所有列的分组前缀
library(dplyr)
library(stringr)
library(limma)

# 提取每个列的分组前缀(从S到_的部分)
col_groups <- str_extract(names(df), "^S\\.[0-9]{0,6}_")
# 去除重复的分组前缀
unique_groups <- unique(col_groups)
  1. 循环处理每个分组,执行归一化
# 初始化空列表存储结果
norm_list <- list()

for (group in unique_groups) {
  # 筛选当前组的列
  group_cols <- df %>% select(starts_with(group))
  # 执行归一化
  norm_data <- group_cols %>% 
    as.matrix() %>% 
    normalizeBetweenArrays(method = "scale") %>% 
    as.data.frame()
  # 存入列表
  norm_list[[group]] <- norm_data
}

# 合并所有归一化后的结果,按原列顺序排列
normalized_df <- bind_cols(norm_list)[names(df)]

方法2:用purrr+dplyr实现批量处理(更简洁)

利用map函数遍历分组,避免显式循环:

library(purrr)

# 按分组前缀拆分列,生成子DataFrame的列表
grouped_dfs <- map(unique_groups, ~df %>% select(starts_with(.x)))

# 对每个子DataFrame执行归一化
norm_grouped_dfs <- map(grouped_dfs, ~.x %>% 
                          as.matrix() %>% 
                          normalizeBetweenArrays(method = "scale") %>% 
                          as.data.frame())

# 合并结果并恢复原列顺序
normalized_df <- bind_cols(norm_grouped_dfs)[names(df)]

关于pivot_longer方法的瓶颈说明

normalizeBetweenArrays要求输入为行对应样本、列对应特征的矩阵结构,你转成长表后反而不符合函数的输入格式要求。直接按列分组处理更贴合该函数的使用场景,不需要额外转置格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:30:51