繁体   English   中英

从分组数据中删除异常值

[英]Remove outlier from grouped data

我有一个数据框如下:

ID Value
A   70
A   80
B   75
C   10
B   50
A   100
C   60
..  ..

我想按ID对数据进行分组,从分组数据(我们从箱线图中看到的)中删除异常值,然后计算均值。

到目前为止,我已经完成了以下工作:

#Summary before removing outliers
summaryBy(Value ~ ID, data = df, FUN = c(mean, median, sd))

df_quantile = do.call("rbind", tapply(df$Value, df$ID, quantile))

filtered = function(x) {
   lowerq = quantile(x)[2]
   upperq = quantile(x)[4]
   iqr = upperq - lowerq

   mild.threshold.upper = (iqr * 1.5) + upperq
   mild.threshold.lower = lowerq - (iqr * 1.5)

   extreme.threshold.upper = (iqr * 3) + upperq
   extreme.threshold.lower = lowerq - (iqr * 3)

   x = x[x > extreme.threshold.lower & x < extreme.threshold.upper]
   return(x)
}

filtData = tapply(df$Value, df$ID, filtered)

移除异常值后,如何在filtData上应用均值sd

由于您提供的数据在箱线图中不包含离群值,因此我使用了一些R数据:您可以保存箱线图,获取离群值,再次将其删除并作图,或者计算每组的平均值。

n <- boxplot(count ~ spray, data = InsectSprays, boxwex=0.25)
InsectSprays_without_outlier <- InsectSprays[-which(InsectSprays$count %in% n$out & InsectSprays$spray %in% c("C","D")), ]
boxplot(count ~ spray, data = InsectSprays_without_outlier, add=T, col=2, at =1:nlevels(InsectSprays$spray) + 0.2, boxwex=0.25)
# mean value per group
aggregate(count ~ spray, data = InsectSprays_without_outlier, mean)

编辑:更一般的解决方案。 必须有一种更优雅的方法,但是您可以尝试以下方法:

# the boxplot to get the stat
n <- boxplot(count ~ spray, data = InsectSprays,boxwex=0.25)
# make a list of your data per group
a <- split(InsectSprays, InsectSprays$spray)
# Go through the list and exclude the outliers
a <- lapply(1:nlevels(InsectSprays$spray), function(i,x) 
  subset(x[[i]], count <= n$stats[5, i] & count >= n$stats[1, i]), a)
# Transform to a data.frame again
InsectSprays_without_outlier <- do.call(rbind, a)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM