如何识别并可视化数据框指定列中被剔除的异常值行?
基于IQR方法标记、分离并可视化待剔除的异常值行
以下是针对需求修改后的完整实现,仅对指定的P-C、P-D、P-E列做异常值分析,自动跳过ID、日期等无关列,同时实现异常行标记、分离和可视化:
1. 准备工作:加载依赖包与导入数据
先导入你的数据集(这里用示例dput数据演示,替换为你的实际数据集即可):
# 示例数据集dput sample_data <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), Date = as.Date(c("2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05", "2024-01-06", "2024-01-07", "2024-01-08", "2024-01-09", "2024-01-10")), `P-C` = c(10, 12, 11, 9, 8, 7, 150, 13, 14, 12), `P-D` = c(20, 22, 21, 19, 18, 17, 23, 24, 300, 22), `P-E` = c(30, 32, 31, 29, 28, 27, 33, 34, 35, 400)), class = "data.frame", row.names = c(NA, -10L)) # 加载所需包 library(dplyr) library(ggplot2) library(tidyr)
2. 指定目标分析列
明确要分析的列,排除ID、日期等无关列:
# 手动指定目标列(替换为你需要的列名) target_cols <- c("P-C", "P-D", "P-E") # 若有大量以"P-"开头的列,也可用正则匹配自动提取: # target_cols <- grep("^P-", names(sample_data), value = TRUE)
3. 标记异常值行
对每个目标列计算IQR上下限,标记该行是否存在异常值:
data_with_outliers <- sample_data %>% # 为每个目标列标记异常状态 mutate( across(all_of(target_cols), ~ case_when( . < quantile(., 0.25) - 1.5*IQR(.) ~ "下侧异常", . > quantile(., 0.75) + 1.5*IQR(.) ~ "上侧异常", TRUE ~ "正常" ), .names = "{col}_异常标记" ), # 标记整行是否为待剔除的异常行(任意目标列异常即判定为异常行) 行状态 = if_else(rowSums(select(., ends_with("异常标记")) == "正常") == length(target_cols), "正常行", "待剔除异常行") )
4. 分离正常行与异常行
# 正常行(用于后续业务分析) normal_data <- data_with_outliers %>% filter(行状态 == "正常行") # 待剔除的异常行(单独查看详情) outlier_rows <- data_with_outliers %>% filter(行状态 == "待剔除异常行") # 打印异常行统计与详情 cat("共识别出", nrow(outlier_rows), "行待剔除异常值,详情:\n") print(outlier_rows)
5. 可视化异常值
方式1:箱线图展示各指标异常点
直观看到每个指标的异常值分布:
# 转换为长格式方便绘图 data_long <- data_with_outliers %>% select(ID, all_of(target_cols), 行状态) %>% pivot_longer(cols = all_of(target_cols), names_to = "监测指标", values_to = "数值") ggplot(data_long, aes(x = 监测指标, y = 数值)) + geom_boxplot(fill = "#cce5ff", alpha = 0.7) + geom_point(aes(color = 行状态), size = 3, alpha = 0.8) + scale_color_manual(values = c("待剔除异常行" = "#dc3545", "正常行" = "#212529")) + labs(title = "各指标异常值分布(IQR方法)", x = "指标名称", y = "指标数值", color = "行状态") + theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
方式2:热力图展示每行异常列
清晰看到每一行哪些列触发了异常标记:
# 整理异常标记数据 outlier_tile <- data_with_outliers %>% select(ID, ends_with("异常标记")) %>% pivot_longer(cols = ends_with("异常标记"), names_to = "监测指标", values_to = "异常状态") %>% mutate(监测指标 = gsub("_异常标记", "", 监测指标), 异常状态 = if_else(异常状态 != "正常", 1, 0)) ggplot(outlier_tile, aes(x = 监测指标, y = factor(ID))) + geom_tile(aes(fill = factor(异常状态)), color = "white") + scale_fill_manual(values = c("0" = "white", "1" = "#dc3545"), labels = c("正常", "异常")) + labs(title = "每行各指标异常情况热力图", x = "指标名称", y = "行ID", fill = "状态") + theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
核心逻辑说明
- 完全匹配你原有的剔除逻辑:只要该行在任意目标列存在IQR异常值,就判定为待剔除行
- 自动跳过ID、日期等无关列,仅对指定的
P-C、P-D、P-E列做分析 - 可视化部分可帮助你快速验证异常值判定的合理性,定位具体异常行和异常列
内容的提问来源于stack exchange,提问作者dragon_cake
相关产品推荐
相关产品推荐

