108

我有一些关于美丽与年龄的多元数据。年龄范围从 20-40 以 2 (20, 22, 24....40) 为间隔,对于每条数据记录,他们被赋予一个年龄和一个从 1-5 的美丽等级。当我绘制这些数据的箱线图时(X 轴上的年龄,Y 轴上的美女评级),在每个框的胡须之外绘制了一些异常值。

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

4

11 回答 11

152

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

x[!x %in% boxplot.stats(x)$out]

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

于 2011-02-08T19:24:08.663 回答
132

好的,您应该将这样的内容应用于您的数据集。不要替换和保存,否则您将破坏您的数据!而且,顺便说一句,您应该(几乎)永远不要从数据中删除异常值:

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
}

要查看它的实际效果:

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()

再一次,你不应该自己做这件事,离群值就是注定的!=)

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

EDIT2:删除quantile了函数,添加了下标,因此使函数更快!=)

在此处输入图像描述

于 2011-01-24T22:47:10.133 回答
32

outline = FALSE做箱线图时作为一个选项使用(阅读帮助!)。

> m <- c(rnorm(10),5,10)
> bp <- boxplot(m, outline = FALSE)

在此处输入图像描述

于 2011-01-24T21:44:29.397 回答
17

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

我故意没有回答具体问题,因为我认为删除“异常值”是统计上的不当行为。我认为不将它们绘制在箱线图中是可以接受的做法,但是仅仅因为它们超过一定数量的标准偏差或一定数量的四分位数宽度而将它们删除是对观察记录的系统和不科学的破坏。

于 2011-01-24T22:04:15.043 回答
11

我查找了与删除异常值相关的包,并找到了这个包(令人惊讶地称为“异常值”!):https
://cran.r-project.org/web/packages/outliers/outliers.pdf 如果你仔细阅读的话查看去除异常值的不同方法,其中我发现rm.outlier最方便使用的一种方法,正如上面链接中所说:“如果异常值被统计测试检测并确认,则此功能可以将其删除或替换为样本均值或中位数”还有来自同一来源的用法部分:
用法

rm.outlier(x, fill = FALSE, median = FALSE, opposite = FALSE)

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

于 2016-12-29T01:10:13.327 回答
9
x<-quantile(retentiondata$sum_dec_incr,c(0.01,0.99))
data_clean <- data[data$attribute >=x[1] & data$attribute<=x[2],]

我发现这很容易去除异常值。在上面的例子中,我只是提取了 2% 到 98% 的属性值。

于 2015-10-23T04:55:07.917 回答
7

不会:

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

很容易完成这项任务?

于 2015-07-28T17:36:11.387 回答
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]) ) 

这将删除第 99 个分位数之外的点。应该像 aL3Xa 所说的保持异常值一样小心。仅应将其删除以获取另一种保守的数据视图。

于 2015-03-19T06:06:52.850 回答
3

一种方法是

my.NEW.data.frame <- my.data.frame[-boxplot.stats(my.data.frame$my.column)$out, ]

或者

my.high.value <- which(my.data.frame$age > 200 | my.data.frame$age < 0) 
my.NEW.data.frame <- my.data.frame[-my.high.value, ]
于 2019-11-20T10:21:16.570 回答
1

异常值与峰值非常相似,因此峰值检测器可用于识别异常值。此处描述的方法使用 z-scores 具有相当好的性能。页面下方的动画说明了异常值或峰值的方法信号。

峰值并不总是与异常值相同,但它们经常相似。

此处显示了一个示例:此数据集通过串行通信从传感器读取。偶尔的串行通信错误、传感器错误或两者都会导致重复的、明显错误的数据点。这一点没有统计价值。它们可以说不是异常值,它们是错误的。z 分数峰值检测器能够在虚假数据点上发出信号并生成干净的结果数据集:在此处输入图像描述

于 2020-08-01T00:45:32.677 回答
-1

试试这个。在函数中输入变量并将 o/p 保存在包含已删除异常值的变量中

outliers<-function(variable){
    iqr<-IQR(variable)
    q1<-as.numeric(quantile(variable,0.25))
    q3<-as.numeric(quantile(variable,0.75))
    mild_low<-q1-(1.5*iqr)
    mild_high<-q3+(1.5*iqr)
    new_variable<-variable[variable>mild_low & variable<mild_high]
    return(new_variable)
}
于 2019-08-14T15:47:31.157 回答