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

基于参考数据集批量计算分组变量异常值Z-score并求和

批量计算分组异常值的Z-score及求和结果

问题背景

我有如下观测数据集:

set.seed(123)
season <- c('spring', 'autumn')
data <- data.frame(id = seq(1:300),
             season = sample(season, 300, replace = TRUE), # 示例额外列1
             weight = rnorm(300, 200, 100), # 示例额外列2
             group = sample(1:8, 300, replace = TRUE),
             albumin = rnorm(300, 5, 3),
             cortisol = rnorm(300, 20, 12),
             calcium = rnorm(300, 6, 0.05))

该数据集包含8组共300条记录,需将albumin、cortisol、calcium(实际场景为20个变量)的每个观测值与对应分组的参考范围对比。

参考范围数据集:

set.seed(123)
reference <- data.frame(group = c(1:8),
                    albumin_lower_limit = rnorm(8, 4.6, 0.3),
                    albumin_mean = rnorm(8, 4.7, 0.3),
                    albumin_sd = rnorm(8, 0.3, 0.01),
                    albumin_upper_limit = rnorm(8, 7.5, 0.3),
                    cortisol_lower_limit = rnorm(8, 7.6, 1.3),
                    cortisol_mean = rnorm(8, 11.8, 1.3),
                    cortisol_sd = rnorm(8, 1.3, 0.01),
                    cortisol_upper_limit = rnorm(8, 16.4, 1.3),
                    calcium_lower_limit = rnorm(8, 8.9, 0.05),
                    calcium_mean = rnorm(8, 9.4, 0.05),
                    calcium_sd = rnorm(8, 0.05, 0.01),
                    calcium_upper_limit = rnorm(8, 11.9, 0.05))

需求说明

  • 对每个分组,若观测值超出对应参考范围(低于下限或高于上限),用该组的参考均值和标准差计算Z-score:z = (x - mean) / sd
  • 生成每个变量的Z-score列(仅异常值有值,正常值为NA或0)
  • 将所有异常变量的Z-score求和得到result列
  • 需自动化批量处理,避免逐个变量编写代码(实际场景为20个变量、1100条记录)

解决方案

使用tidyverse工具链实现批量处理,无需逐个变量硬编码:

1. 加载依赖包

library(tidyverse)

2. 合并观测数据与参考数据

通过group字段将两个数据集合并,使每条观测对应其分组的参考范围:

merged_data <- data %>%
  left_join(reference, by = "group")

3. 批量计算各变量的Z-score

提取目标变量列表,然后用across批量处理每个变量:

# 定义需要处理的目标变量(实际场景可直接替换为20个变量的列表)
target_vars <- c("albumin", "cortisol", "calcium")

# 批量计算Z-score:异常值计算Z值,正常值设为NA(如需设为0,替换NA_real_为0)
result_data <- merged_data %>%
  mutate(
    across(
      all_of(target_vars),
      .fns = list(z_score = ~ if_else(
        .x < get(str_c(cur_column(), "_lower_limit")) | .x > get(str_c(cur_column(), "_upper_limit")),
        (.x - get(str_c(cur_column(), "_mean"))) / get(str_c(cur_column(), "_sd")),
        NA_real_
      )),
      .names = "{.col}_z_score"
    )
  )
  • cur_column()自动获取当前处理的变量名,拼接对应的参考字段,无需手动指定每个变量的上下限、均值和标准差
  • 正常观测值设为NA,求和时会自动忽略;若需要正常值显示为0,将NA_real_替换为0即可

4. 计算result列(异常Z-score求和)

提取所有Z-score列,按行求和并忽略NA:

result_data <- result_data %>%
  mutate(result = rowSums(select(., ends_with("_z_score")), na.rm = TRUE))

5. (可选)清理冗余列

如果不需要保留参考范围的原始字段,可移除:

result_data_clean <- result_data %>%
  select(-matches("(lower_limit|mean|sd|upper_limit)$"))

结果扩展说明

该代码可直接适配实际场景的20个变量,只需修改target_vars列表为所有需要处理的变量名称即可,无需修改核心逻辑,完全实现自动化批量处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:57:48