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

如何在R的tidyverse中高效实现多列除以单列生成新列

用tidyverse高效批量处理列除法

针对你的需求,直接用mutate()结合across()就能高效完成批量列的除法运算,完全不需要多次调用mutate。以下是具体实现方案:

1. 先模拟一个示例数据集(方便你测试)

library(tidyverse)

# 构造测试数据:2列标识列 + 多个value列,共5万行
set.seed(123)
df <- tibble(
  gene_name = paste0("gene_", 1:50000),
  gene_length = sample(100:1000, 50000, replace = TRUE),
  value1 = rnorm(50000, 100, 20),
  value2 = rnorm(50000, 200, 30),
  value3 = rnorm(50000, 150, 25),
  value4 = rnorm(50000, 300, 40),
  value5 = rnorm(50000, 250, 35)
)

2. 批量执行除法并生成标准化列

核心代码如下,会自动将所有value开头的列除以gene_length,并生成带_norm后缀的新列:

df_norm <- df %>%
  mutate(
    across(
      .cols = starts_with("value"),  # 选择所有以value开头的列
      .fns = ~ .x / gene_length,     # 执行除法:当前列 / gene_length
      .names = "{.col}_norm"         # 新列名规则:原列名 + _norm
    )
  )

3. 灵活调整列选择规则

如果你的value列命名规则不是以value开头,或者需要指定列位置,可以替换.cols参数:

  • 用正则匹配列名:匹配value后接数字的列:matches("value\\d+")
  • 用列位置选择:前两列是标识列,从第3列到第21列是目标列:3:21
  • 排除特定列:除了gene_name和gene_length之外的所有列:-c(gene_name, gene_length)

示例:用列位置选择的写法

df_norm <- df %>%
  mutate(
    across(
      .cols = 3:21,
      .fns = ~ .x / gene_length,
      .names = "{.col}_norm"
    )
  )

为什么这个方法高效?

across()是tidyverse专为批量列操作设计的函数,它底层是向量化运算,不会像循环或多次mutate那样产生额外的性能开销,完全能轻松处理5万行的数据集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:15:33