Ignorar los valores atípicos en gplplot2 boxplot

¿Cómo ignoraría los valores atípicos en ggplot2 boxplot? No quiero simplemente que desaparezcan (es decir, outlier.size = 0), pero quiero que se ignoren de manera que el eje y se escale para mostrar el percentil 1º / 3º. Mis valores atípicos están causando que la “caja” se reduzca tan pequeña que prácticamente es una línea. ¿Hay algunas técnicas para lidiar con esto?

Editar Aquí hay un ejemplo:

y = c(.01, .02, .03, .04, .05, .06, .07, .08, .09, .5, -.6) qplot(1, y, geom="boxplot") 

enter image description here

Aquí hay una solución usando boxplot.stats

 # create a dummy data frame with outliers df = data.frame(y = c(-100, rnorm(100), 100)) # create boxplot that includes outliers p0 = ggplot(df, aes(y = y)) + geom_boxplot(aes(x = factor(1))) # compute lower and upper whiskers ylim1 = boxplot.stats(df$y)$stats[c(1, 5)] # scale y limits based on ylim1 p1 = p0 + coord_cartesian(ylim = ylim1*1.05) 

Utilice geom_boxplot(outlier.shape = NA) para no mostrar los valores atípicos y scale_y_continuous(limits = c(lower, upper)) para cambiar los límites del eje.

Un ejemplo.

 n < - 1e4L dfr <- data.frame( y = exp(rlnorm(n)), #really right-skewed variable f = gl(2, n / 2) ) p <- ggplot(dfr, aes(f, y)) + geom_boxplot() p # big outlier causes quartiles to look too slim p2 <- ggplot(dfr, aes(f, y)) + geom_boxplot(outlier.shape = NA) + scale_y_continuous(limits = quantile(dfr$y, c(0.1, 0.9))) p2 # no outliers plotted, range shifted 

En realidad, como Ramnath mostró en su respuesta (y Andrie también en los comentarios), tiene más sentido recortar las escalas después de calcular la estadística, a través de coord_cartesian .

 coord_cartesian(ylim = quantile(dfr$y, c(0.1, 0.9))) 

(Probablemente aún necesite usar scale_y_continuous para arreglar los saltos de eje.)

Tuve el mismo problema y precalculamos los valores para Q1, Q2, mediana, ymin, boxplot.stats usando boxplot.stats :

 # Load package and generate data library(ggplot2) data < - rnorm(100) # Compute boxplot statistics stats <- boxplot.stats(data)$stats df <- data.frame(x="label1", ymin=stats[1], lower=stats[2], middle=stats[3], upper=stats[4], ymax=stats[5]) # Create plot p <- ggplot(df, aes(x=x, lower=lower, upper=upper, middle=middle, ymin=ymin, ymax=ymax)) + geom_boxplot(stat="identity") p 

El resultado es un diagtwig de caja sin valores atípicos. enter image description here

Una idea sería personalizar los datos en un procedimiento de dos pasos:

  1. ejecutar un primer pase, conocer cuáles son los límites, por ejemplo, corte en un percentil dado, o N desviación estándar por encima de la media, o …

  2. en una segunda pasada, establezca los valores más allá del límite dado al valor de ese límite

Debo enfatizar que este es un método anticuado que debería estar dominado por técnicas robustas más modernas, pero todavía se lo encuentra mucho.

La opción “coef” de la función geom_boxplot permite cambiar el límite de valores atípicos en términos de rangos intercuartílicos. Esta opción está documentada para la función stat_boxplot. Para desactivar los valores atípicos (en otras palabras, se tratan como datos regulares), uno puede, en lugar de usar el valor predeterminado de 1.5, especificar un valor límite muy alto:

 library(ggplot2) # generate data with outliers: df = data.frame(x=1, y = c(-10, rnorm(100), 10)) # generate plot with increased cutoff for outliers: ggplot(df, aes(x, y)) + geom_boxplot(coef=1e30) 

Si desea obligar a los bigotes a extenderse a los valores máximos y mínimos, puede modificar el argumento del coef . El valor predeterminado para coef es 1.5 (es decir, la longitud predeterminada de los bigotes es 1.5 veces el IQR).

 # Load package and create a dummy data frame with outliers #(using example from Ramnath's answer above) library(ggplot2) df = data.frame(y = c(-100, rnorm(100), 100)) # create boxplot that includes outliers p0 = ggplot(df, aes(y = y)) + geom_boxplot(aes(x = factor(1))) # create boxplot where whiskers extend to max and min values p1 = ggplot(df, aes(y = y)) + geom_boxplot(aes(x = factor(1)), coef = 500) 

imagen de p0

imagen de p1

 for( i in match(rownames(TT),rownames(data))){ File=paste('HNSC-',rownames(data)[i],".png",sep="") Name< -unlist(lapply(colnames(data),function(x) unlist(strsplit(x,"-TCGA"))[1])) type<-unlist(lapply(Name,function(x) unlist(strsplit(x,"-"))[2])) input<-data.frame(lncRNA=as.numeric(as.character(data[i,])),Name,type) p<-ggplot(input,aes(Name,lncRNA,fill=factor(type))) p<-p+geom_boxplot(outlier.shape=NA) max<-max(tapply(input$lncRNA,input$Name,function(x) quantile(x,0.975))) min<-min(tapply(input$lncRNA,input$Name,function(x) quantile(x,0))) p<-p+coord_flip(ylim = c(min, max)) p ggsave(File) }