从分组数据中删除异常值

时间:2016-04-26 11:02:20

标签: r quantile

我有一个数据框如下:

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

上应用mean,sd?

1 个答案:

答案 0 :(得分:1)

由于您提供的数据在箱线图中没有包含异常值,因此我使用了一些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)