我想在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对象中提取异常值信息。但是,像这样标签可能会重叠。
非常感谢: - )
答案 0 :(得分:6)
我用debug(boxplot.with.outlier.label)
看了一眼,然后......结果是函数中有一个bug
。
错误发生在第125行,其中data.frame DATA
由x
,y
和label_name
构成。
以前x
和y
已重新排序,而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)
答案 1 :(得分:1)
intelligent point label placement是一个单独的问题here或here。没有终极和理想的解决方案,所以你只需要选择一个。
因此,您将使用标签覆盖正常的箱线图,如下所示:
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)