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

使用dplyr对R DataFrame数值列按行计算zscores出现NA的问题求助

问题分析与解决方法

为什么原代码返回NA?

使用rowwise()后,mutate_if(is.numeric, ~scale(.))会对每个数值列的单个单元格执行scale()函数。单个数值的标准差为0,scale()计算时会除以这个0,最终得到NA结果。

可行实现方法

方法1:dplyr原生语法(rowwise + c_across)

利用c_across()获取每行所有数值列的向量,再逐列计算z-score:

library(dplyr)

df %>%
  rowwise() %>%
  mutate(
    across(where(is.numeric), 
           ~ (. - mean(c_across(where(is.numeric)))) / sd(c_across(where(is.numeric)))
    )
  ) %>%
  ungroup() # 取消行分组,避免后续操作受影响

方法2:基础R + apply按行处理

直接提取数值列,用apply按行计算z-score后替换原列:

# 筛选数值型列的位置
num_cols <- sapply(df, is.numeric)
# 按行计算z-score并转置(apply返回结果是列优先,需要转置匹配原数据)
df[num_cols] <- t(apply(df[num_cols], 1, function(x) (x - mean(x)) / sd(x)))

方法3:tidyr宽转长再转宽

适合需要对行内数据做更多中间处理的场景:

library(dplyr)
library(tidyr)

df %>%
  mutate(row_id = row_number()) %>% # 添加行标识
  pivot_longer(cols = where(is.numeric), names_to = "col", values_to = "value") %>%
  group_by(row_id) %>%
  mutate(z_score = (value - mean(value)) / sd(value)) %>%
  pivot_wider(names_from = "col", values_from = "z_score") %>%
  select(-row_id) %>%
  bind_cols(df %>% select(where(~!is.numeric(.)))) %>% # 合并非数值列
  select(all_of(names(df))) # 恢复原数据的列顺序

内容的提问来源于stack exchange,提问作者swathi.upadhya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:09:24