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

在R中对DataFrame多列执行特定归一化计算的技术咨询

问题描述

我有一个包含25000行、51列的DataFrame,前几行数据结构如下:

chr1_12750000_12760000  2   8   7   3   5   7   15  11 .......  10
chr11_11280000_11290000 8   6   7   8   7   12  10  10 .......  10
chr9_21700000_21710000  2   2   0   0   2   3   1   0 .......   0
chr1_162500000_162510000    0   2   2   3   4   3   4   3 .......   4
chr11_53780000_53790000 9   7   4   3   3   2   3   6 .......   8
chrX_157610000_157620000    5   10  5   8   17  13  15  9 .......   11
chr4_134170000_134180000    0   0   1   0   1   0   3   2 .......   2
chr1_62090000_62100000  8   15  15  16  7   9   10  20 .......  6
chr2_16540000_16550000  5   1   3   6   7   10  9   8 .......   0
chr6_57740000_57750000  2   2   1   2   1   2   4   4 .......   5

需要对n2至n51列(即第2到第51列)逐列执行以下操作:

  • 按当前列的值对DataFrame降序排序
  • 获取排序后第1250行的该列数值
  • 将该列所有数值除以这个第1250行的数值

解决方案

方法一:Base R 实现

用apply函数遍历目标列,直接完成计算:

# 定义要处理的列范围
target_cols <- 2:51

# 逐列执行计算并覆盖原列
df[target_cols] <- apply(df[target_cols], 2, function(col) {
  # 对当前列降序排序
  sorted_vals <- sort(col, decreasing = TRUE)
  # 提取排序后第1250位的数值
  cutoff_val <- sorted_vals[1250]
  # 列所有值除以cutoff_val
  col / cutoff_val
})

注:不需要对整个DataFrame排序,单独对当前列排序即可得到相同的目标数值,这样能提升计算效率。

方法二:Tidyverse(dplyr)实现

如果习惯tidyverse语法,用mutate(across())可以更简洁地完成:

library(dplyr)

# 简洁写法
df <- df %>%
  mutate(across(2:51, ~ .x / sort(.x, decreasing = TRUE)[1250]))

注意事项

  • 提前检查目标列排序后第1250位是否为0,避免出现除以0的错误:
    cutoff_check <- sapply(df[target_cols], function(col) {
      sort(col, decreasing = TRUE)[1250]
    })
    # 输出值为0的列索引
    which(cutoff_check == 0)
    
  • 25000行数据量下,两种方法的效率都足够,无需额外优化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:07:49