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

在dplyr中按行计算几何均值实现变量标准化的问题

问题核心

需要对iris数据集的指定列(Sepal.Length、Sepal.Width)做行级标准化:每行的列值除以该行这两个列的几何均值,但原代码错误使用整列数据计算几何均值,导致结果不符预期。

原代码问题分析

原代码中psych::geometric.mean(c(Sepal.Length,Sepal.Width))是将整个Sepal.Length列和Sepal.Width列的所有值合并成一个向量,计算的是全局几何均值,而非每行两个值的几何均值。

正确实现方式

方法1:使用rowwise() + c_across()(推荐的dplyr风格)

通过rowwise()让dplyr按行处理数据,c_across()提取每行指定列的数值组成向量,再计算行级几何均值:

library(dplyr)
library(psych)

coln1 <- colnames(iris)[1:2]

iris_processed <- iris %>%
  rowwise() %>%
  # 计算每行指定列的几何均值
  mutate(row_geo_mean = geometric.mean(c_across(all_of(coln1)))) %>%
  # 对指定列做标准化
  mutate(across(all_of(coln1), ~ .x / row_geo_mean)) %>%
  # 取消行分组,避免后续操作受影响
  ungroup()

# 验证第一行结果:和预期一致
iris_processed[1, coln1]
# Sepal.Length Sepal.Width 
#      1.207107      0.83944

方法2:用自定义几何均值函数

如果不想依赖psych包,替换成你自己的gm_mean函数即可:

gm_mean = function(x, na.rm=TRUE){
  exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}

iris_processed <- iris %>%
  rowwise() %>%
  mutate(row_geo_mean = gm_mean(c_across(all_of(coln1)))) %>%
  mutate(across(all_of(coln1), ~ .x / row_geo_mean)) %>%
  ungroup()

方法3:用.by = row_number()实现行级分组(dplyr 1.1.0+支持)

无需显式调用rowwise(),直接按行分组处理:

iris_processed <- iris %>%
  mutate(
    across(all_of(coln1), ~ .x / geometric.mean(pick(all_of(coln1)))),
    .by = row_number()
  )
关键说明
  • c_across()/pick()用于在每行中提取指定列的数值,确保几何均值是行级计算
  • 处理完成后取消行分组(ungroup())是必要的,避免后续聚合类操作(如summarise)出现非预期的行级结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:31:18