2013-03-03 194 views
5

我想将矩阵的每一列绘制为箱形图,然后将每个箱形图中的异常值标记为它们在矩阵中所属的行名称。为了给出一个例子:在R中的箱形图上标注异常值

vv=matrix(c(1,2,3,4,8,15,30),nrow=7,ncol=4,byrow=F) 
rownames(vv)=c("one","two","three","four","five","six","seven") 
boxplot(vv) 

我便想在每个小区离群值(在本例中30)作为行名称属于,所以在这种情况下,30属于第7行有一个简单的如何做到这一点?我已经看到类似的问题,但没有人按照我希望的方式工作。

+0

对不起,我们走了。 – user1836894 2013-03-03 00:35:15

回答

3

在给出的例子中有点无聊,因为它们都是同一行。但这里是代码:

bxpdat <- boxplot(vv) 
text(bxpdat$group,            # the x locations 
    bxpdat$out,            # the y values 
    rownames(vv)[which(vv == bxpdat$out, arr.ind=TRUE)[, 1]], # the labels 
    pos = 4) 

这挑选具有等于在boxplot结果中的“出”列表(即,异常值)值的rownames。 Boxplot调用并返回boxplot.stats的值。看一看:

str(bxpdat) 
+0

如果有一个数据点是一个异常点而不是另一个点,那么如果存在两个不同方法的盒图,这是否不会错误地标记异常值? – 2013-03-03 00:47:34

+0

欢迎您发表一个代表您的疑虑的例子。我只在发布的问题中看到一个boxplot。 – 2013-03-03 00:49:03

4

@迪文的解决方案非常适用于单箱线图,但对于任何失败,重复的值,就像我所创建的数据集:

#Create data 
set.seed(1) 
basenums <- c(1,2,3,4,8,15,30) 
vv=matrix(c(basenums, sample(basenums), 1-basenums, 
      c(0, 29, 30, 31, 32, 33, 60)),nrow=7,ncol=4,byrow=F) 
dimnames(vv)=list(c("one","two","three","four","five","six","seven"), 1:4) 

在这个数据集, @迪文的解决方案为:

enter image description here

哪个是假的,因为在第4个例子,这是不可能的最小值和最大值是在T他同一排。

这个解决方案是可怕的(我希望可以简化),但有效。

#Reshape data 
vv_dat <- as.data.frame(vv) 
vv_dat$row <- row.names(vv_dat) 
library(reshape2) 
new_vv <- melt(vv_dat, id.vars="row") 

#Get boxplot data 
bxpdat <- as.data.frame(boxplot(value~variable, data=new_vv)[c("out", "group")]) 

#Get matches with boxplot data 
text_guide <- do.call(rbind, apply(bxpdat, 1, 
    function(x) new_vv[new_vv$value==x[1]&new_vv$variable==x[2], ])) 

#Add labels 
with(text_guide, text(x=as.numeric(variable)+0.2, y=value, labels=row)) 

enter image description here

0

或者你可以简单地运行从this blog post代码:

source("https://raw.githubusercontent.com/talgalili/R-code-snippets/master/boxplot.with.outlier.label.r") # Load the function 
set.seed(6484) 
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) 

(其中处理多个离群它们彼此接近)

enter image description here

+0

代码源不再有效 – 2016-07-06 11:23:13

+1

谢谢@DavidPell - 我修复了它的使用:https://raw.githubusercontent.com/talgalili/R-code-snippets/master/boxplot.with.outlier.label.r – 2016-10-09 06:51:31

0

@塞巴斯蒂安-C 这似乎与更多的一般性工作

bx1<-boxplot(pb,las=2,cex.axis=.8) 
if(length(bx1$out)!=0){ 
    ## get the row of each outlier 
    out.rows<-sapply(1:length(bx1$out),function(i) which(vv[,bx1$group[i]]==bx1$out[i])) 
    text(bx1$group,bx1$out, 
    rownames(vv)[out.rows], 
    pos=4 
) 
} 
4

有一个简单的方法。请注意,Boxplot中以下行中的b是大写字母。

library(car) 

Boxplot(y ~ x, id.method="y")