在R中的boxplot上标记异常值

时间:2013-03-03 00:28:08

标签: r label boxplot outliers

我想将矩阵的每一列绘制成一个箱线图,然后将每个箱图中的异常值标记为它们在矩阵中所属的行名称。举个例子:

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行。有一种简单的方法可以做到这一点吗?我已经看到类似的问题,但似乎没有一个按照我想要的方式工作。

6 个答案:

答案 0 :(得分:8)

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

library(car)

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

答案 1 :(得分:5)

或者,您可以使用{car}包中的“Boxplot”功能为您标记异常值。

请参阅以下链接:https://CRAN.R-project.org/package=car

答案 2 :(得分:4)

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

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结果中的“out”列表(即异常值)的值的rownames。 Boxplot调用并返回boxplot.stats的值。看看:

 str(bxpdat)

答案 3 :(得分:4)

@Ddin的解决方案适用于单个boxplot,但对于具有重复值的任何内容都会失败,例如我创建的数据集:

#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)

在这个数据集上,@ DWin的解决方案给出了:

enter image description here

这是错误的,因为在第4个例子中,最小值和最大值不可能在同一行。

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

#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

答案 4 :(得分: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

答案 5 :(得分:0)

@塞巴斯蒂安-C 这是对DWin解决方案的略微修改,似乎更具普遍性

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
  )
}