2011-10-28 117 views
5

我想在R中绘制箱图并为离群值添加名称。到目前为止,我发现了this solutionBoxplot离群值在R中标记

那里的函数提供了我需要的所有功能,但是它错误地打乱了标签。在以下示例中,它将异常值标记为“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

更新:我把这个错误塔尔加利利的关注,而w /以小时为单位,他发布了不再出现此问题的编辑版本的脚本。 –

回答

6

我拿了起来看看这款debug(boxplot.with.outlier.label),而且......原来有一个在功能bug

错误发生在行125上,其中data.frame DATAx,ylabel_name构造而成。

此前xy已被重新排序,而lab_y还没有。当提供的价值x(你的x1)本身不是已经准备好的时候,你会得到你经历的那种j ling。

作为一个立即解决,你可以预购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

+0

Josh:谢谢。^_^ –

+0

谢谢乔希。前几天我遇到了同样的问题,所以这是一个很好的帮助+1 – pssguy

+1

很高兴提供帮助。由于这看起来对其他人来说是有用的,所以我只是给脚本的作者发了电子邮件,因为他在脚本中发现错误时要求用户执行操作。 –

1

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

所以,你会overplot带标签的普通箱线图,如下:

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。完成后,您只需按下“停止”。 请注意,每个异常值可以有多个标签!在我的解决方案中,我只是简单地选择了第一个! PS:我为for循环感到羞耻,但不知道如何对它进行矢量化 - 随时可以改进。

编辑:灵感来自Federico's link现在我发现它可以做得更容易!只是这2个命令:

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

identify()解决方案很好,但它不可扩展,我有数百个地块,我必须将它们打印为PDF :-) –