删除后:离群值接近最大值,保留在 R 箱线图中

After deletion: outliers near maximum, remaining in R boxplot

在 R 中创建一个函数后,该函数应该 return 一个用 NA 代替某些数据的离群值向量,我得到的离群值保持在最大值附近:

kill_outliers <- function(data, na.rm=TRUE){
  q <- quantile(data, probs=c(0.25, 0.75), na.rm=na.rm)
  killed <- data
  intq <- 1.5 * IQR(data, na.rm=na.rm)
  killed[x < (q[1]-intq)] <- NA
  killed[x > (q[2]+intq)] <- NA
  killed
}

使用此函数后 boxplot(killed) 显示:

为什么会有异常值?我试过:

killed[x > (q[2] + intq)] <- NA

假设这是小于或等于的问题,但它并没有改变任何东西。

(q[2] + intq) == 216.87,删除后排序数据集中的最后一个值是 216.16,应该适合。 另外,我不明白为什么当我使用第 3 个分位数 (q[3] + intq) 时,它根本没有排除任何异常值...

编辑

如机器所示,问题在于创建具有新 IQR 的新数据集。因此我得出结论,boxplot() 创建了一个新的图来估计每个数据集的 IQR。附加问题:有没有办法将新数据集与之前由箱线图创建的图相匹配,从而使值与之前的分位数相匹配?

您的函数删除了异常值,因此,您获得了具有 new IQR 的新变量分布。使用新的 IQR,其他值可以是离群值,而这些值与原始变量的 IQR 不是离群值(因此不会被杀死)。因此,只要存在异常值,您就需要一次又一次地重新运行您的函数。

这里有一段代码,只要有异常值就会运行:

kill_outliers <- function(data, na.rm=TRUE){
q <- quantile(data, probs=c(0.25, 0.75), na.rm=na.rm)
  intq <- 1.5*IQR(data, na.rm=na.rm)
intq_low <- q[1]-intq
intq_high <- q[1]+intq

killed <- data
while(any(killed < intq_low, na.rm=TRUE) | any(killed > intq_high, na.rm= TRUE)){ 
  killed[killed<intq_low] <- NA
  killed[killed>intq_high] <- NA

q <- quantile(killed, probs=c(0.25, 0.75), na.rm=na.rm)
  intq <- 1.5*IQR(killed, na.rm=na.rm)
intq_low <- q[1]-intq
intq_high <- q[1]+intq
}
killed
}

boxplot(kill_outliers(rnorm(9999)))

此外,在您的函数中有一个未定义的对象扩展 x,它可能在您的环境中并且也会导致问题。

@machine 是对的,删除 "outliers" 将更改分布及其参数。

我想补充一点,如果没有重要的理由,永远不要删除异常值。事实上,一个点超过箱形图中的晶须并不是这样的原因。少量附近值是完全正常的,而大量此类点可能被视为非正态分布的指标。在这种情况下,我宁愿避免使用离群值这个词,而是用不同的方式来称呼它,例如极端值。

set.seed(765)
boxplot(rnorm(100))    # normal distribution
boxplot(rt(100, df=3)) # t distribution with long tails
boxplot(rlnorm(100))   # lognormal, skewed

所有这些示例都不符合移除异常值的条件。另一种情况是,当某些点是由单独的 "process" 创建的,比通常的方差或测量误差大。

boxplot(c(rnorm(100), 7))

在这里,可以应用异常值测试,例如outlierTest 来自包 car,具有 Bonferroni 校正:

library(car)
outlierTest(lm(x ~ 1))

很明显,这样的测试不能重复应用。

搜索 crossvalidated,你会发现几篇关于异常值问题的好文章,例如whether to delete cases that are flagged as outliers ... or is it cheating to drop the outliers based on the boxplot ...