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

如何在大数据集中用循环结合rowMeans函数批量计算新变量

高效计算多疾病题项行均值的解决方案

问题背景

我有一份宽格式疾病数据集,包含54种疾病,每种疾病对应18个题项,变量命名规则为epi_scm.1至epi_scm.18、ms_scm.1至ms_scm.18这类(前缀是疾病名称,后缀是题项序号)。需要为每种疾病计算其18个题项的行均值,但手动逐个处理效率太低,希望找到高效的实现方式。

我之前尝试过逐个子集化数据的方法,但耗时太长,不适合主分析:

#Subset data to include only 42 columns
subset_epi <- df4[, 1:42]  # Replace 1:42 with the indices or column names of the columns I want to keep
subset_epi <- subset_epi[complete.cases(subset_epi), ]

#Organize index numbers subset
rownames(subset_epi) <- 1:nrow(subset_epi)
dim(subset_epi)

#New variable Morality = Mean Score for Morality
subset_epi$Morality <- rowMeans(na.omit(subset_epi[, c("epi_scm_1", "epi_scm_2", "epi_scm_3", "epi_scm_4", "epi_scm_5")]))

方法1:Base R 循环(无需额外包)

通过提取疾病前缀批量处理,适合不想加载第三方包的场景:

# 提取所有唯一的疾病前缀(匹配`xxx_scm`格式)
disease_prefixes <- unique(sub("\\.\\d+$", "", colnames(df4)))
disease_prefixes <- disease_prefixes[grepl("_scm", disease_prefixes)]

# 循环计算每个疾病的行均值
for(prefix in disease_prefixes) {
  # 匹配当前前缀对应的所有题项列
  target_cols <- grep(paste0("^", prefix, "\\."), colnames(df4), value = TRUE)
  # 计算行均值,na.rm=TRUE表示忽略缺失值,按需调整
  df4[[paste0(prefix, "_mean")]] <- rowMeans(df4[, target_cols], na.rm = TRUE)
}

方法2:tidyverse 风格实现(dplyr + stringr)

代码更简洁,适合熟悉tidyverse生态的用户:

library(dplyr)
library(stringr)

df4 <- df4 %>%
  # 针对所有符合规则的题项列,计算对应疾病的行均值
  mutate(across(matches("_scm\\.\\d+"), 
                .fns = list(mean = ~ rowMeans(select(cur_data(), starts_with(str_remove(cur_column(), "\\.\\d+$"))), na.rm = TRUE)),
                .names = "{str_remove(.col, '\\.\\d+')}_mean")) %>%
  # 去重重复生成的均值列(每个题项都会生成一次,保留唯一的均值列)
  select(-matches("_scm\\.\\d+_mean_\\d+")) %>%
  rename_with(~ str_remove(., "_mean_\\d+"), matches("_scm_mean_\\d+"))

方法3:data.table 实现(大数据集最优)

对于超大规模数据集,data.table的效率远高于base R和tidyverse:

library(data.table)
setDT(df4)

# 筛选所有目标题项列
target_cols <- colnames(df4)[grepl("_scm\\.\\d+", colnames(df4))]
# 提取唯一的疾病前缀
disease_prefixes <- unique(sub("\\.\\d+$", "", target_cols))

# 批量计算行均值
for(prefix in disease_prefixes) {
  df4[, paste0(prefix, "_mean") := rowMeans(.SD, na.rm = TRUE), .SDcols = grep(paste0("^", prefix, "\\."), target_cols, value = TRUE)]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:55:05