基于条件替换数据框值:将偏离均值1倍标准差的值设为NA
基于列范围的数据清洗方案
问题背景
给定如下生成的数据框:
set.seed(10) df <- data.frame(a1 = rnorm(7), b1 = rnorm(7), c1 = rnorm(7), a2 = rnorm(7), b2 = rnorm(7), c2 = rnorm(7)) df <- round(abs(df), 2) df <- df%>%mutate(group1_avg=rowMeans(across(ends_with("1"))), .after=3, group2_avg=rowMeans(across(ends_with("2")))) df <- df%>%mutate(group1_std=rowSds(as.matrix(df[endsWith(names(df), "1")])), .after=4, group2_std=rowSds(as.matrix(df[endsWith(names(df), "2")]))) df <- df%>%relocate(group2_avg, .after=last_col()) df <- df%>%relocate(group2_std, .after=last_col())
初始数据状态:
df a1 b1 c1 group1_avg group1_std a2 b2 c2 group2_avg group2_std 1 0.02 0.36 0.74 0.3733333 0.3601851 2.19 0.10 1.44 1.2433333 1.0587886 2 0.18 1.63 0.09 0.6333333 0.8643109 0.67 0.25 0.36 0.4266667 0.2177919 3 1.37 0.26 0.95 0.8600000 0.5604463 2.12 1.85 1.76 1.9100000 0.1873499 4 0.60 1.10 0.20 0.6333333 0.4509250 1.27 0.08 0.32 0.5566667 0.6293118 5 0.29 0.76 0.93 0.6600000 0.3315117 0.37 0.97 0.65 0.6633333 0.3002221 6 0.39 0.24 0.48 0.3700000 0.1212436 0.69 0.18 1.09 0.6533333 0.4561067 7 1.21 0.99 0.60 0.9333333 0.3089229 0.87 1.38 0.76 1.0033333 0.3308071
需求
- 对第一组数值列(示例中
a1-c1):若值超出group1_avg ± group1_std范围,设为NA,否则保留原值 - 对第二组数值列(示例中
a2-c2):执行相同逻辑,对应group2_avg和group2_std - 要求通过列范围而非列名指定目标列,避免依赖列名变化
目标效果
df a1 b1 c1 group1_avg group1_std a2 b2 c2 group2_avg group2_std 1 0.02 0.36 NA 0.3733333 0.3601851 2.19 NA 1.44 1.2433333 1.0587886 2 0.18 NA 0.09 0.6333333 0.8643109 NA 0.25 0.36 0.4266667 0.2177919 3 1.37 NA 0.95 0.8600000 0.5604463 NA 1.85 1.76 1.9100000 0.1873499 4 0.60 NA 0.20 0.6333333 0.4509250 NA 0.08 0.32 0.5566667 0.6293118 5 NA 0.76 NA 0.6600000 0.3315117 NA NA 0.65 0.6633333 0.3002221 6 0.39 0.24 0.48 0.3700000 0.1212436 0.69 NA 1.09 0.6533333 0.4561067 7 1.21 0.99 NA 0.9333333 0.3089229 0.87 NA 0.76 1.0033333 0.3308071
解决方案代码
library(dplyr) library(matrixStats) # 执行数据清洗 df_processed <- df %>% mutate( # 处理第一组:列1-3,参考列4(group1_avg)和列5(group1_std) across(1:3, ~ifelse(.x >= (group1_avg - group1_std) & .x <= (group1_avg + group1_std), .x, NA)), # 处理第二组:列6-8,参考列9(group2_avg)和列10(group2_std) across(6:8, ~ifelse(.x >= (group2_avg - group2_std) & .x <= (group2_avg + group2_std), .x, NA)) ) # 查看处理后结果 df_processed
代码说明
- 批量列处理:用
dplyr::across()指定列范围(如1:3),无需依赖列名,适配列顺序变化场景 - 范围判断逻辑:通过
ifelse()检查每个值是否落在均值±标准差区间内,超出则替换为NA - 灵活调整:若列顺序发生变化,只需修改
across()中的列索引,以及对应均值/标准差的引用位置即可
内容的提问来源于stack exchange,提问作者gingerbreadbeer
相关产品推荐
相关产品推荐

