200 votes

Ignorer les valeurs aberrantes dans les boxplot ggplot2

Comment ignorer les valeurs aberrantes dans un graphique ggplot2 ? Je ne veux pas simplement qu'elles disparaissent (c'est-à-dire outlier.size=0), mais je veux qu'elles soient ignorées de façon à ce que l'axe des y affiche le 1er/3ème percentile. Mes valeurs aberrantes font que la "boîte" se rétrécit tellement qu'il s'agit pratiquement d'une ligne. Existe-t-il des techniques pour résoudre ce problème ?

Editer En voici un exemple :

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

enter image description here

299voto

Richie Cotton Points 35365

Utilisation geom_boxplot(outlier.shape = NA) pour ne pas afficher les valeurs aberrantes et scale_y_continuous(limits = c(lower, upper)) pour modifier les limites de l'axe.

Un exemple.

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 fait, comme Ramnath l'a montré dans sa réponse (et Andrie aussi dans les commentaires), il est plus logique de recadrer les échelles après avoir calculé la statistique, via coord_cartesian .

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

(Vous devrez probablement encore utiliser scale_y_continuous pour corriger les ruptures d'axe).

164voto

Ramnath Points 24798

Voici une solution utilisant 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)

18voto

Matthias Munz Points 513

J'ai eu le même problème et j'ai précalculé les valeurs pour Q1, Q2, la médiane, ymin, ymax en utilisant 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

Le résultat est un diagramme en boîte sans valeurs aberrantes. enter image description here

12voto

Dirk Eddelbuettel Points 134700

Une idée serait de winsoriser les données selon une procédure en deux étapes :

  1. Dans un premier temps, apprenez quelles sont les limites, par exemple la coupure d'un percentile donné, ou N écart-type au-dessus de la moyenne, ou ...

  2. dans une deuxième passe, fixer les valeurs au-delà de la borne donnée à la valeur de cette borne

Je tiens à souligner qu'il s'agit d'une démodé méthode qui devrait être dominée par des méthodes plus techniques modernes robustes mais on la rencontre encore souvent.

7voto

Dongdong Kong Points 163

gg.layers::geom_boxplot2 est exactement ce que vous voulez.

# remotes::install_github('rpkgs/gg.layers')
library(gg.layers)
library(ggplot2)
p <- ggplot(mpg, aes(class, hwy))
p + geom_boxplot2(width = 0.8, width.errorbar = 0.5)

https://rpkgs.github.io/gg.layers/reference/geom_boxplot2.html enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X