Ignora i valori anomali nel boxplot di ggplot2

Come ignorerei i valori anomali nel boxplot di ggplot2? Non voglio semplicemente che scompaiano (es. Outlier.size = 0), ma voglio che vengano ignorati in modo tale che l’asse y si riduca a mostrare il 1/3 percentile. I miei valori anomali stanno facendo sì che la “scatola” si restringa in modo così piccolo che praticamente è una linea. Ci sono alcune tecniche per affrontare questo?

Modifica Ecco un esempio:

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

inserisci la descrizione dell'immagine qui

Ecco una soluzione utilizzando 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) 

Usa geom_boxplot(outlier.shape = NA) per non visualizzare i scale_y_continuous(limits = c(lower, upper)) anomali e scale_y_continuous(limits = c(lower, upper)) per modificare i limiti dell’asse.

Un esempio.

 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 

In realtà, come Ramnath ha mostrato nella sua risposta (e anche Andrie nei commenti), ha più senso ritagliare le scale dopo aver calcolato la statistica, tramite coord_cartesian .

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

(Probabilmente dovrai ancora utilizzare scale_y_continuous per correggere le interruzioni dell'asse.)

Ho avuto lo stesso problema e ho precalcolato i valori di Q1, Q2, mediana, ymin, ymax 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 

Il risultato è un boxplot senza valori anomali. inserisci la descrizione dell'immagine qui

Un’idea sarebbe quella di ottenere i risultati in una procedura in due passaggi:

  1. eseguire una prima passata, imparare quali sono i limiti, ad es. taglio di un dato percentile, o N deviazione standard sopra la media, o …

  2. in un secondo passaggio, imposta i valori oltre il limite dato al valore di tale limite

Dovrei sottolineare che questo è un metodo vecchio stile che dovrebbe essere dominato da tecniche più moderne e robuste, ma lo si incontra ancora molto.

L’opzione “coef” della funzione geom_boxplot consente di modificare il valore di soglia in termini di intervalli interquartili. Questa opzione è documentata per la funzione stat_boxplot. Per distriggersre i valori anomali (in altre parole vengono considerati dati regolari), anziché utilizzare il valore predefinito di 1.5, è ansible specificare un valore di taglio molto elevato:

 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) 

Se vuoi forzare i baffi ad estendere i valori massimo e minimo, puoi modificare l’argomento coef . Il valore predefinito per coef è 1.5 (ovvero la lunghezza predefinita dei baffi è 1.5 volte l’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) 

immagine di p0

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