如何在R中实现data.frame每列每10行值除以其后两行平均值
解决data.frame分组样本除以对应校验行平均值的问题
需求说明
将data.frame中每一组10个样本行的各列数值,除以该组之后紧接着的两行校验行(如check1_1与check2_1)的平均值。比如示例数据里,第1-10行的每个值要除以第11-12行的平均值,第13-22行除以第23-24行的平均值,以此类推。
示例数据
df <- structure(list( sample_grp = c("sample1", "sample2", "sample3", "sample4", "sample5", "sample6", "sample7", "sample8", "sample9", "sample10", "check1_1", "check2_1", "sample11", "sample12", "sample13", "sample14", "sample15", "sample16", "sample17", "sample18", "sample19", "sample20", "check1_2", "check2_2"), col1 = c(0.6578, 0.03456, 0.567, 0.001, 0.8796, 0.345, 0.26891, 0.56293, 0.0345, 0.5678, 0.98649, 0.9235, 0.5436, 0.1236, 0.00234, 0.546, 0.356, 0.4567, 0.4577, 0.4356, 0.4568, 0.2314, 0.457, 0.8769) ), class = "data.frame", row.names = c(NA, -24L))
解决方案
方法一:Base R 实现
通过标记分组、提取校验均值、匹配计算三步完成:
# 1. 给每行打分组标记:每12行(10样本+2校验)为一个大组,校验行标记为NA group_id <- rep(seq(1, nrow(df)/12), each = 12) check_rows <- c(11:12, 23:24) # 对应示例里的校验行位置,可按需扩展 group_id[check_rows] <- NA # 2. 计算每个大组内校验行的平均值 check_means <- tapply(df$col1, group_id, function(x) mean(df$col1[group_id == unique(x[!is.na(x)]) & is.na(group_id)])) # 3. 对样本行执行除法,生成归一化后的列 df$col1_normalized <- ifelse(is.na(group_id), df$col1, df$col1 / check_means[group_id])
方法二:data.table 实现
适合大数据量场景,分组操作更高效:
library(data.table) dt <- as.data.table(df) # 1. 按每12行划分大组 dt[, big_group := rep(seq(.N/12), each = 12)] # 2. 计算每个大组内校验行的平均值 check_means_dt <- dt[grepl("^check", sample_grp), .(mean_val = mean(col1)), by = big_group] # 3. 合并均值到原表,对样本行做归一化 dt <- merge(dt, check_means_dt, by = "big_group", all.x = TRUE) dt[!grepl("^check", sample_grp), col1_normalized := col1 / mean_val] # 可选:清理临时列 dt[, c("big_group", "mean_val") := NULL]
结果说明
处理后新增的col1_normalized列就是样本行除以对应校验组平均值后的结果,校验行保持原有数值(如果不需要保留校验行,可通过dt[!grepl("^check", sample_grp)]或df[!is.na(group_id), ]过滤)。
内容的提问来源于stack exchange,提问作者pemb_bex6789
相关产品推荐
相关产品推荐

