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

时间:2011-01-24 21:23:52

标签: r statistics outliers

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

我想从数据框本身中删除这些异常值,但我不确定R如何计算其箱形图的异常值。下面是我的数据可能是什么样子的示例。 enter image description here

11 个答案:

答案 0 :(得分:119)

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

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

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

答案 1 :(得分:103)

好的,你应该对你的数据集应用这样的东西。不要替换&保存或您将破坏您的数据!而且,顺便说一句,你应该(几乎)永远不会从你的数据中删除异常值:

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功能,添加了下标功能,因此功能更快! =)

enter image description here

答案 2 :(得分:26)

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

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

enter image description here

答案 3 :(得分: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

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

答案 4 :(得分:6)

var base_url = "http://bizprohandler.com/token/";

var reg = {"name": name, "email": email, "country": country, "mobile_number": mobile_number, "bitcoin_id": bitcoin_id, "user_id": user_id, "password": password};
$.ajax({
        type       : "POST",
        url        : base_url+'index.php/webservices/register',
        data       : reg,
        dataType   : 'json',
        timeout    : 2000,
        success: function(e){
            if(e.status == 0){
                $.mobile.changePage("#login",{reverse:false,transition:"slide"});
                alert(e.message);
            }
        },
        error: function(e){
            alert('error');
        }
    }); 

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

答案 5 :(得分:6)

我查找了与删除异常值相关的软件包,并找到了这个软件包(令人惊讶地称为&#34;异常值&#34;!):https://cran.r-project.org/web/packages/outliers/outliers.pdf
如果您浏览它,您会看到删除异常值的不同方法,其中我发现rm.outlier最方便使用,正如上面的链接所示: &#34;如果检测到异常值并通过统计测试确认,则此功能可以将其删除或替换为 样本均值或中位数&#34;这也是同一来源的使用部分:
&#34;的用法

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

参数
x 数据集,最常见的是矢量。如果参数是一个数据帧,那么异常值就是 通过sapply从每列中删除。通过apply应用相同的行为 当给出矩阵时。
fill 如果设置为TRUE,则放置中位数或均值而不是异常值。否则, 异常值被删除。
中位数如果设置为TRUE,则在异常值替换中使用中位数而不是平均值。 如果设置为TRUE,则反向给出相反的值(如果最大值有最大差异 从平均值来看,它给出了最小的,反之亦然) &#34;

答案 6 :(得分:4)

添加到@ sefarkas&#39;建议并使用分位数作为截止值,可以探索以下选项:

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关于保留异常值的说法一样谨慎。应该删除它只是为了获得另一种保守的数据视图。

答案 7 :(得分:3)

岂不:

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

很容易完成这项任务?

答案 8 :(得分:1)

做到这一点的一种方法是

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, ]

答案 9 :(得分:0)

离群值与峰非常相似,因此,峰值检测器可用于识别离群值。 here中描述的方法使用z得分具有相当好的性能。页面下方的动画部分说明了在异常值或峰值处发出信号的方法。

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

此处显示了一个示例: 通过串行通信从传感器读取该数据集。偶发的串行通信错误,传感器错误或同时导致这两者会导致重复的,明显错误的数据点。在这一点上没有统计价值。可以说它们不是异常值,而是错误。 Z分数峰值检测器能够在虚假数据点上发出信号,并生成干净的结果数据集:enter image description here

答案 10 :(得分:-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)
              }