在R中创建一个函数后,该函数应返回一个用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
}
使用此功能后,箱形图(已杀死)显示:
为什么有离群值?我尝试过:
killed[x > (q[2] + intq)] <- NA
假设是更少或相等的问题,但是它并没有改变任何东西。
(q[2] + intq) == 216.87
,删除后排序后的数据集中的最后一个值是216.16
,应该合适。
另外,我不明白为什么,当我使用第三分位数(q[3] + intq)
时,根本没有排除任何异常值...
如机器所示,问题在于使用新的IQR创建新的数据集。因此,我得出结论,boxplot()创建了一个新的图,用于估计每个数据集的IQR。另一个问题:是否有办法将新数据集拟合到由boxplot创建的前一个图,以使值适合前一个分位数?
答案 0 :(得分:0)
您的函数将删除异常值,从而使用 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)))
此外,您的函数中还有一个未定义的objext x
,它可能在您的环境中也可能导致问题。
答案 1 :(得分:0)
@machine是正确的,删除“异常值”将更改分布及其参数。
我想补充一点,没有严重的原因,绝不能删除异常值。一个点超过箱线图中的晶须的事实并不是这种原因。少量的闭口值完全是正态的,而大量的此类点可被视为非正态分布的指标。在这种情况下,我宁愿避免使用“离群值”一词,而改称“离群值”极端值。
set.seed(765)
boxplot(rnorm(100)) # normal distribution
boxplot(rt(100, df=3)) # t distribution with long tails
boxplot(rlnorm(100)) # lognormal, skewed
所有这些示例均不符合异常值删除的条件。另一种情况是,某些点是由一个比通常的方差或测量误差大的单独“过程”创建的。
boxplot(c(rnorm(100), 7))
此处,可以应用离群值测试,例如outlierTest
来自软件包汽车,具有Bonferroni校正功能:
library(car)
outlierTest(lm(x ~ 1))
很明显,这种测试不能重复进行。
交叉验证搜索,您会发现几篇有关异常值问题的好文章,例如whether to delete cases that are flagged as outliers ...或is it cheating to drop the outliers based on the boxplot ...