分组(聚类)数据异常值检测:R语言逐集群IQR剔除的for循环实现咨询
R语言按聚类分组逐群IQR异常值剔除实现代码
核心实现逻辑
你可以通过for循环逐组提取数据、计算组内IQR阈值、筛选正常数据后合并得到全量清洗后的数据,无需修改原数据集的对应子集,实现逻辑如下:
完整可运行代码
library("ggstatsplot") # 读取原始数据 df <- read.csv("C:/Users/gadmin/Desktop/dataE.csv", header = TRUE) # 初始化空数据框,存储所有组剔除异常值后的结果 clean_df <- data.frame() # 遍历所有唯一的cluster分组(适配cluster编号不连续的场景) for (current_cluster in unique(df$cluster)) { # 提取当前分组的子集 sub_df <- df[df$cluster == current_cluster, ] # 计算当前分组repair.price的IQR阈值 Q <- quantile(sub_df$repair.price, probs = c(.25, .75), na.rm = FALSE) iqr <- IQR(sub_df$repair.price) up <- Q[2] + 1.5 * iqr low <- Q[1] - 1.5 * iqr # 剔除当前分组的异常值 sub_clean <- subset(sub_df, repair.price > low & repair.price < up) # 将当前分组清洗后的数据拼接到结果数据框 clean_df <- rbind(clean_df, sub_clean) } # 输出全量数据处理前后的分布对比图 ggbetweenstats(df, cluster, repair.price, outlier.tagging = TRUE, title = "处理前全量数据分布") ggbetweenstats(clean_df, cluster, repair.price, outlier.tagging = TRUE, title = "处理后全量数据分布")
如果你要严格使用你给出的序号循环结构,可将循环部分替换为如下代码:
# 提取所有唯一的cluster列表 cluster_list <- unique(df$cluster) for(i in 1:length(cluster_list)) { current_cluster <- cluster_list[i] sub_df <- df[df$cluster == current_cluster, ] Q <- quantile(sub_df$repair.price, probs = c(.25, .75), na.rm = FALSE) iqr <- IQR(sub_df$repair.price) up <- Q[2] + 1.5 * iqr low <- Q[1] - 1.5 * iqr sub_clean <- subset(sub_df, repair.price > low & repair.price < up) clean_df <- rbind(clean_df, sub_clean) }
注意事项
- 该方案默认每个cluster分组的数据量足够计算上下四分位数,如果存在分组样本量过小的情况,可在循环内加判断逻辑跳过或特殊处理
- 如果你需要保留原始数据的行顺序,可在最终清洗完成后对
clean_df按原始行号排序即可
内容的提问来源于stack exchange,提问作者armin yadollahi
相关产品推荐
相关产品推荐

