R语言:在swiss数据集绘图后添加马氏距离异常点时points()无效
解决R语言散点图矩阵添加异常点无效果的问题
嗨,我来帮你搞定这个问题!你遇到的核心问题是:plot(swiss)生成的是多变量散点图矩阵(n×n的子图网格,每个子图对应一对变量的散点),而直接用points(outliers)根本无法匹配每个子图的变量组合,自然看不到效果。下面给你详细的原因分析和解决方案:
问题根源
当你调用plot(swiss)时,R底层其实调用了pairs()函数生成散点图矩阵。此时整个绘图窗口被分割成多个子图,points()默认只会在当前激活的最后一个子图(也就是矩阵右下角的子图)上尝试添加点,而且你直接传入数据框outliers时,R只会把数据框的第一列当作x轴、第二列当作y轴来绘制,完全没有对应到每个子图的变量对,所以看起来毫无效果。
解决方案
推荐两种方法,其中第一种更简洁可靠:
方法1:用pairs()自定义面板函数(推荐)
直接通过pairs()的panel参数,自定义每个子图的绘制逻辑,让每个子图都能同时画出常规点和异常点:
# 1. 计算马氏距离并定位异常点的行号 mu_hat <- apply(swiss, 2, mean) sigma_hat <- cov(swiss) mahalanobis_distance <- mahalanobis(swiss, mu_hat, sigma_hat) # 用行号标记异常点,后续更方便定位 outlier_rows <- which(mahalanobis_distance > 10) # 2. 自定义面板函数:先画所有点,再叠加异常点 my_panel <- function(x, y, ...) { # 绘制当前变量对的所有散点 points(x, y, ...) # 叠加当前变量对的异常点,用红色叉号标记 points(x[outlier_rows], y[outlier_rows], pch = 'x', col = 'red', cex = 1.2) } # 3. 生成带异常点的散点图矩阵 pairs(swiss, panel = my_panel)
方法2:给已生成的散点图矩阵逐个添加异常点
如果你已经用plot(swiss)画出了基础图,也可以通过切换子图的方式逐个添加异常点,不过这种方法相对繁琐:
# 1. 先画出基础散点图矩阵 plot(swiss) # 2. 计算异常点行号(和方法1一致) mu_hat <- apply(swiss, 2, mean) sigma_hat <- cov(swiss) mahalanobis_distance <- mahalanobis(swiss, mu_hat, sigma_hat) outlier_rows <- which(mahalanobis_distance > 10) # 3. 遍历每个子图,切换并添加异常点 n_vars <- ncol(swiss) for (i in 1:n_vars) { for (j in 1:n_vars) { # 切换到第i行、第j列的子图 par(mfg = c(i, j)) # 在当前子图添加对应变量对的异常点 points(swiss[outlier_rows, j], swiss[outlier_rows, i], pch = 'x', col = 'red') } }
验证效果
运行上面的代码后,你会看到所有子图里的异常点都被用红色叉号标记出来了,完美解决你之前的问题~
内容的提问来源于stack exchange,提问作者tulians
相关产品推荐
相关产品推荐

