我有一个数据框如下:
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
答案 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)