R中的Boxplot异常值标记

时间:2011-10-28 12:54:31

标签: r

我想在R中绘制箱图并为异常值添加名称。到目前为止,我找到了this solution

那里的功能提供了我需要的所有功能,但它不正确地标记标签。在下面的示例中,它将异常值标记为“u”而不是“o”:

library(plyr)
library(TeachingDemos)
source("http://www.r-statistics.com/wp-content/uploads/2011/01/boxplot-with-outlier-label-r.txt") # Load the function
set.seed(1500)
y <- rnorm(20)
x1 <- sample(letters[1:2], 20,T)
lab_y <- sample(letters, 20)
# plot a boxplot with interactions:
boxplot.with.outlier.label(y~x1, lab_y)

你知道任何解决方案吗? ggplot2库非常好,但没有提供这样的功能(据我所知)。我的替代方法是使用text()函数并从boxplot对象中提取异常值信息。但是,像这样标签可能会重叠。

非常感谢: - )

2 个答案:

答案 0 :(得分:6)

我用debug(boxplot.with.outlier.label)看了一眼,然后......结果是函数中有一个bug

错误发生在第125行,其中data.frame DATAxylabel_name构成。

以前xy已重新排序,而lab_y尚未重新排序。如果提供的x(您的x1)值本身已经按顺序排列,您将会遇到您遇到的那种混乱。

作为即时修复,您可以预先订购x这样的值(或做更优雅的事情)

df <- data.frame(y, x1, lab_y, stringsAsFactors=FALSE)
df <- df[order(df$x1), ]
# Needed since lab_y is not searched for in data (though it probably should be)
lab_y <- df$lab_y  

boxplot.with.outlier.label(y~x1, lab_y, data=df)

Boxplot produced by procedure described above

答案 1 :(得分:1)

intelligent point label placement是一个单独的问题herehere。没有终极和理想的解决方案,所以你只需要选择一个。

因此,您将使用标签覆盖正常的箱线图,如下所示:

set.seed(1501)
y <- c(4, 0, 7, -5, rnorm(16))
x1 <- c("a", "a", "b", "b", sample(letters[1:2], 16, T))
lab_y <- sample(letters, 20)

bx <- boxplot(y~x1)

out_lab <- c()
for (i in seq(bx$out)) { 
    out_lab[i] <- lab_y[which(y == bx$out[i])[1]]
}

identify(bx$group, bx$out, labels = out_lab, cex = 0.7)

然后,在identify()运行期间,您只需单击以定位您想要标签的位置, 正如here所述。完成后,只需按“STOP”即可。 请注意,每个异常值可以有多个标签!在我的解决方案中,我只是选择了第一个!!

PS:我对for循环感到羞愧,但不知道如何对其进行矢量化 - 随意发布改进。

编辑:受到Federico's link的启发,现在我觉得它可以轻松完成!只是这两个命令:

boxplot(y~x1)
identify(as.integer(as.factor(x1)), y, labels = lab_y, cex = 0.7)