对于近似正态分布的数据,箱形图是快速可视化数据的中值和散布以及任何异常值的好方法。
但是,对于更重尾的分布,很多点显示为离群值,因为离群被定义为不在IQR的固定因子范围内,而对于重尾分布,这种情况当然会更频繁地发生。
那么人们使用什么可视化此类数据呢?还有更适应的东西吗?如果重要的话,我在R上使用ggplot。
对于近似正态分布的数据,箱形图是快速可视化数据的中值和散布以及任何异常值的好方法。
但是,对于更重尾的分布,很多点显示为离群值,因为离群被定义为不在IQR的固定因子范围内,而对于重尾分布,这种情况当然会更频繁地发生。
那么人们使用什么可视化此类数据呢?还有更适应的东西吗?如果重要的话,我在R上使用ggplot。
Answers:
在OP似乎有问题的关键是,他们有非常重尾数据-我不认为目前大多数的答案实际上这个问题处理在所有的,所以我推动我以前的一个答案评论。
如果您确实想保留箱形图,则下面列出了一些选项。我在R中创建了一些数据,这些数据显示了基本问题:
set.seed(seed=7513870)
x <- rcauchy(80)
boxplot(x,horizontal=TRUE,boxwex=.7)
数据的中间部分缩小为几毫米宽的小条。相同的问题困扰着其他大多数建议-包括QQ图,带状图,蜂箱/蜂巢图和小提琴图。
现在,一些潜在的解决方案:
1)变换,
如果对数或倒数产生可读的箱线图,则可能是一个很好的主意,并且原始刻度仍可以显示在轴上。
最大的问题是有时没有“直观”的转变。还有一个较小的问题,即分位数本身可以很好地进行单调变换,而栅栏则不能。如果仅对转换后的数据进行箱线绘图(如我在此处所做的那样),则晶须的x值将不同于原始图。
在这里,我使用了反双曲正弦(asinh)。它的尾部有点像对数,类似于接近零的线性,但是人们通常不会发现它是一种直观的变换,因此,除非像log这样的相当直观的变换很明显,否则我一般不建议使用此选项。为此的代码:
xlab <- c(-60,-20,-10,-5,-2,-1,0,1,2,5,10,20,40)
boxplot(asinh(x),horizontal=TRUE,boxwex=.7,axes=FALSE,frame.plot=TRUE)
axis(1,at=asinh(xlab),labels=xlab)
2)缩放比例破坏-采取极端离群值并将其压缩到两端的狭窄窗口中,压缩比例远大于中心。如果您这样做,我强烈建议您在整个范围内彻底休息。
opar <- par()
layout(matrix(1:3,nr=1,nc=3),heights=c(1,1,1),widths=c(1,6,1))
par(oma = c(5,4,0,0) + 0.1,mar = c(0,0,1,1) + 0.1)
stripchart(x[x< -4],pch=1,cex=1,xlim=c(-80,-5))
boxplot(x[abs(x)<4],horizontal=TRUE,ylim=c(-4,4),at=0,boxwex=.7,cex=1)
stripchart(x[x> 4],pch=1,cex=1,xlim=c(5,80))
par(opar)
3)修剪极端离群值(通常我不建议您不要非常清楚地指出这一点,但是它看起来像下一个图,两端都没有“ <5”和“ 2>”),并且
4)我称之为极端的“箭头”-与修整类似,但修整后的值计数在每一端均指示
xout <- boxplot(x,range=3,horizontal=TRUE)$out
xin <- x[!(x %in% xout)]
noutl <- sum(xout<median(x))
nouth <- sum(xout>median(x))
boxplot(xin,horizontal=TRUE,ylim=c(min(xin)*1.15,max(xin)*1.15))
text(x=max(xin)*1.17,y=1,labels=paste0(as.character(nouth)," >"))
text(x=min(xin)*1.17,y=1,labels=paste0("< ",as.character(noutl)))
就我个人而言,我至少喜欢使用带抖动的带状图来了解数据。下面的图是R中的晶格(对不起,ggplot2)。我喜欢这些情节,因为它们很容易解释。如您所说,这样做的原因之一是没有任何变换。
df <- data.frame(y1 = c(rnorm(100),-4:4), y2 = c(rnorm(100),-5:3), y3 = c(rnorm(100),-3:5))
df2 <- stack(df)
library(lattice)
stripplot(df2$values ~ df2$ind, jitter=T)
该beeswarm包提供了stripplot一个伟大的选择(感谢@January您的建议)。
beeswarm(df2$values ~ df2$ind)
与您的数据,因为它的近似正态分布,另一件事尝试可能是一个qqplot,qqnorm在这种情况下。
par(mfrow=c(1,3))
for(i in 1:3) { qqnorm(df[,i]); abline(c(0,0),1,col="red") }
beeswarm
软件包中的图甚至比R中的带状图好。
您可以坚持使用箱线图。定义晶须有不同的可能性。根据尾部的厚度,样本数量和对异常值的容忍度,您可以选择两个或多个或两个以上的极值分位数。鉴于您的问题,我将避免通过IQR定义的晶须。
当然,除非您要转换数据,否则这种情况会使理解变得更加困难。