如何从数据集中删除异常值

Dan*_*n Q 92 statistics r outliers

我有一些美丽与年龄的多元数据.年龄范围为20-40,间隔为2(20,22,24 ...... 40),并且对于每个数据记录,它们的年龄和美容等级为1-5.当我对这些数据进行箱形图(横跨X轴的年龄,Y轴上的美观评级)时,在每个框的胡须外面都会绘制一些异常值.

我想从数据框本身中删除这些异常值,但我不确定R如何计算其箱形图的异常值.下面是我的数据可能是什么样子的示例. 在此输入图像描述

J. *_*in. 125

没有人发布最简单的答案:

x[!x %in% boxplot.stats(x)$out]
Run Code Online (Sandbox Code Playgroud)

另见:http://www.r-statistics.com/2011/01/how-to-label-all-the-outliers-in-a-boxplot/

  • 真的很优雅.谢谢.但是如果分布有多种模式并且异常值确实只有少量且分散,则需要小心. (4认同)
  • 提及它不会改变数据集也很重要.这只是一种过滤方法.因此,如果您打算在没有异常值的情况下使用数据集,请将其分配给变量.例如`result = x [!x%in%boxplot.stats(x)$ out]` (2认同)
  • 只有一行代码并不一定意味着它很简单!理解一行代码并不总是那么容易,特别是对于初学者来说,并且没有注释。 (2认同)

aL3*_*3xa 112

好的,你应该对你的数据集应用这样的东西.不要更换和保存,否则你会破坏你的数据!而且,顺便说一下,你应该(几乎)永远不会从你的数据中删除异常值:

remove_outliers <- function(x, na.rm = TRUE, ...) {
  qnt <- quantile(x, probs=c(.25, .75), na.rm = na.rm, ...)
  H <- 1.5 * IQR(x, na.rm = na.rm)
  y <- x
  y[x < (qnt[1] - H)] <- NA
  y[x > (qnt[2] + H)] <- NA
  y
}
Run Code Online (Sandbox Code Playgroud)

要看到它的实际效果:

set.seed(1)
x <- rnorm(100)
x <- c(-10, x, 10)
y <- remove_outliers(x)
## png()
par(mfrow = c(1, 2))
boxplot(x)
boxplot(y)
## dev.off()
Run Code Online (Sandbox Code Playgroud)

再一次,你永远不应该自己这样做,异常值只是意味着!=)

编辑:我添加na.rm = TRUE为默认.

EDIT2:删除了quantile功能,添加了下标,从而使功能更快!=)

在此输入图像描述

  • 你不应该在stackoverflow上询问任务问题! (9认同)
  • 这是否意味着我们也不应该回答它?=) (6认同)
  • 好的,我在这里遗漏了一些东西.您想要从数据中删除异常值,因此您可以使用`boxplot`绘制它们.这是可以管理的,你应该记下@Prasad的回答,因为回答了你的问题.如果你想通过使用"异常值规则"`q +/-(1.5*H)`来排除异常值,那么运行一些分析,然后使用这个函数.顺便说一句,我是从头开始做的,没有谷歌搜索,所以我有可能用我的这个功能重新启动了轮子...... (3认同)
  • "异常值只是意味着"?不必要.它们可能来自测量误差,必须彻底检查.当异常值太大时,它可能意味着什么,或者不是那么多.这就是为什么(至少在生物学中)中位数通常更多地表示人口而不是平均数. (3认同)

Pra*_*ani 27

outline = FALSE在执行箱线图时使用作为选项(阅读帮助!).

> m <- c(rnorm(10),5,10)
> bp <- boxplot(m, outline = FALSE)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 实际上,这将从boxplot本身中删除异常值,但我想从数据框中删除异常值. (4认同)
  • 我看,然后@Joshua说你需要查看boxplot函数返回的数据(特别是列表中的`out`和`group`项). (2认同)

42-*_*42- 16

boxplot函数返回用于进行绘图的值(实际上由bxp()完成:

bstats <- boxplot(count ~ spray, data = InsectSprays, col = "lightgray") 
#need to "waste" this plot
bstats$out <- NULL
bstats$group <- NULL
bxp(bstats)  # this will plot without any outlier points
Run Code Online (Sandbox Code Playgroud)

我故意没有回答具体问题,因为我认为删除"异常值"是统计上的弊端.我认为不将它们绘制在箱线图中是可以接受的做法,但删除它们是观察记录的系统性和不合理的重整.

  • 那么,回答这个问题而不知道问题的原因也不是一个好的做法.是的,从数据中删除"异常值"并不好,但有时您需要没有异常值的数据来执行特定任务.在我最近的统计分配中,我们不得不想象一个没有异常值的集合,以确定用于数据的最佳回归模型.那有! (4认同)
  • 我不是在考虑你在这方面可能得出的建议,"确定最好的回归模型"是特别有说服力的.相反,如果你需要删除离群隐约规定的目的,那么我认为这反映不佳对谁劝它,而不是我的立场无效的是证据的人. (4认同)

小智 8

我查找了与删除异常值相关的软件包,并找到了这个软件包(令人惊讶地称为"异常值"!):https ://cran.r-project.org/web/packages/outliers/outliers.pdf
如果你通过它看到去除异常值的不同方法,其中我找到了rm.outlier最方便的方法,正如它在上面的链接中所说:"如果通过统计测试检测并确认异常值,则此函数可以删除它或替换样本均值或中位数"以及来自同一来源的使用部分:
" 用法

rm.outlier(x, fill = FALSE, median = FALSE, opposite = FALSE)
Run Code Online (Sandbox Code Playgroud)

参数
x 数据集,最常见的是向量.如果argument是一个数据帧,那么将通过sapply从每列中删除异常值.给出矩阵时,应用相同的行为.
fill 如果设置为TRUE,则放置中位数或平均值而不是异常值.否则,简单地删除异常值.
中位数 如果设置为TRUE,则在异常值替换中使用中位数而不是平均值.如果设置为TRUE则相反,给出相反的值(如果最大值与平均值有最大差异,则给出最小值,反之亦然)"


Gau*_*are 7

x<-quantile(retentiondata$sum_dec_incr,c(0.01,0.99))
data_clean <- data[data$attribute >=x[1] & data$attribute<=x[2],]
Run Code Online (Sandbox Code Playgroud)

我发现这很容易删除异常值.在上面的例子中,我只是提取2百分位到98百分位的属性值.


Kar*_*ikS 5

添加到@sefarkas 的建议并使用分位数作为截止点,可以探索以下选项:

newdata <- subset(mydata,!(mydata$var > quantile(mydata$var, probs=c(.01, .99))[2] | mydata$var < quantile(mydata$var, probs=c(.01, .99))[1]) ) 
Run Code Online (Sandbox Code Playgroud)

这将删除超过第 99 个分位数的点。应该像 aL3Xa 所说的保持异常值一样小心。只有在获得另一种保守的数据视图时才应该删除它。


d8a*_*nja 5

不会:

z <- df[df$x > quantile(df$x, .25) - 1.5*IQR(df$x) & 
        df$x < quantile(df$x, .75) + 1.5*IQR(df$x), ] #rows
Run Code Online (Sandbox Code Playgroud)

轻松完成此任务?