如何用R将dataFrame每行所有元素除以distances列表对应值?
在R中实现DataFrame每行元素除以对应行的距离值
以下是几种高效的实现方式,适用于你提到的15167行的datExpr和对应长度的distances列表:
方法1:矩阵广播(最高效,推荐)
先将distances列表转换为向量(如果原本就是向量可跳过这一步),再利用R的矩阵广播特性直接运算,速度远快于循环或apply:
# 将列表转为向量 distances_vec <- unlist(distances) # 转换DataFrame为矩阵并执行逐行除法 datExpr_mat <- as.matrix(datExpr) datExpr_normalized <- datExpr_mat / distances_vec # 可选:将结果转回DataFrame datExpr_normalized <- as.data.frame(datExpr_normalized)
原理:当矩阵与一个长度等于矩阵行数的向量做除法时,R会自动将向量按行重复,实现每行元素除以对应位置的距离值。
方法2:使用apply函数
如果更习惯用apply处理行操作,也可以这样写:
distances_vec <- unlist(distances) datExpr_normalized <- t(apply(datExpr, 1, function(row, d) row / d[as.integer(rownames(row))], d = distances_vec)) datExpr_normalized <- as.data.frame(datExpr_normalized)
注:t()用于转置结果,因为apply按行处理后返回的是列优先的矩阵,需要转置回原行结构。
方法3:tidyverse/dplyr风格
如果你熟悉tidyverse生态,用dplyr可以更直观地处理:
library(dplyr) distances_vec <- unlist(distances) # 创建包含行号和距离值的辅助表,合并后逐列计算 datExpr_normalized <- datExpr %>% mutate(row_num = row_number()) %>% left_join(tibble(row_num = seq_along(distances_vec), dist = distances_vec), by = "row_num") %>% mutate(across(-c(row_num, dist), ~ .x / dist)) %>% select(-row_num, -dist)
内容的提问来源于stack exchange,提问作者Recep Durgut
相关产品推荐
相关产品推荐

