如何计算每年均值以上数据子组的标准差?(R语言)
修正后的R代码及说明
需求说明
针对数据集中的每一年,对每个COMP列执行以下操作:
- 计算该年份该列所有非NA值的均值
- 筛选出该年份该列中高于均值的非NA值组成子组
- 计算该子组的标准差
原代码的错误点
- 列选择错误:
across(c(1:4))包含了第一列Year,应该排除年份列,仅选择COMP1到COMP4 .by = Year参数位置错误:该参数属于summarize函数,不应嵌套在sd函数内- 子组筛选逻辑混乱:错误使用赋值符号
=而非比较逻辑,且多余的sum操作完全偏离需求,正确逻辑是直接筛选高于均值的元素
修正后的代码
library(dplyr) # 测试数据 Year <- c(2001, 2001, 2001, 2001, 2002, 2002, 2002, 2002, 2003, 2003, 2003, 2003, 2004, 2004, 2004, 2004) COMP1 <- c(NA, 1, 2, 6, 9, NA, 2, 1, NA, 2, 9, 6, NA, 1, 8, 5) COMP2 <- c(2, 3, 3, 3, 6, 4, 1, 0, 1, 3, 6, 1, NA, 1, 8, 8) COMP3 <- c(NA, 1, 2, 3, 4, 0, 0, 1, 0, 4, 2, 2, 1, NA, 1, 1) COMP4 <- c(25, 29, 16, 17, NA, 20, NA, 21, 12, 17, 31, 32, 21, 1, 2, 1) DF <- data.frame(Year, COMP1, COMP2, COMP3, COMP4) # 计算子组标准差 SUBGROUP <- DF %>% group_by(Year) %>% summarize( across(COMP1:COMP4, ~ { col_mean <- mean(.x, na.rm = TRUE) # 筛选非NA且高于均值的元素 above_mean_vals <- .x[!is.na(.x) & .x > col_mean] # 子组元素≥2时计算标准差,否则返回NA if(length(above_mean_vals) >= 2) sd(above_mean_vals) else NA }, .names = "sd_above_mean_{.col}" ), .groups = "drop" ) print(SUBGROUP)
代码细节说明
group_by(Year):按年份分组,保证每个年份的计算独立进行across(COMP1:COMP4):指定要处理的目标列,也可替换为across(-Year)直接排除年份列- 自定义计算逻辑:
- 先提取当前列当前年份的非NA均值
- 精准筛选符合条件的子组数据
- 增加子组元素数量判断,避免单个元素无法计算标准差的报错
.names参数:自动生成带标识的结果列名,便于区分对应原列.groups = "drop":计算完成后取消分组,返回常规数据框格式
运行输出结果
Year sd_above_mean_COMP1 sd_above_mean_COMP2 sd_above_mean_COMP3 sd_above_mean_COMP4 1 2001 NA NA 0.7071068 2.8284271 2 2002 5.6568542 1.4142136 2.8284271 NA 3 2003 2.1213203 2.1213203 2.8284271 0.7071068 4 2004 2.1213203 0.0000000 NA NA
内容的提问来源于stack exchange,提问作者Li4991
相关产品推荐
相关产品推荐

