Moustaches à 5 et 95% pour box-plot

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Julie LEGER
Messages : 3
Enregistré le : 21 Nov 2008, 17:03

Moustaches à 5 et 95% pour box-plot

Messagepar Julie LEGER » 24 Nov 2008, 08:35

Bonjour,

Je suis biostatisticienne et je découvre R progressivement, principalement ses fonctions graphiques qui me paraissent très puissantes. :D

Je suis en train de faire des box-plots, mais en lisant la documentation avec avec attention, je me suis rendue compte que la longueur des moustaches dépendent de l'intervalle interquartile et du range. Or j'aurais voulu faire des box-plots avec des moustaches représentant les percentiles 5% et 95%.

En parcourant le forum, je n'ai pas vu de solution (peut-être que je n'ai pas bien cherché) donc je me demandais si vous auriez une astuce pour me permettre de faire des box-plots ayant de moustaches à 5 et 95% :?:

Merci par avance pour votre aide.

Julie LEGER

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 24 Nov 2008, 10:06

Bonjour,

Fait attention le boxplot est un type de représentation avec ces codes, je dirai que c'est un graphique standardisé. Chaque élément de ce graphique à un sens et une signification, voir Boxplot.
Le graphique que tu souhaites réaliser pourrait ne pas être bien interprérté ou compris par d'autres personnes les visualisant.
Néanmoins en modifiant un peu les fonctions de base du boxplot c'est possible :

Code : Tout sélectionner

boxplot2 <- function (x, ...) UseMethod("boxplot2")
 
boxplot2.default <- function (x, ..., range = 1.5, width = NULL, varwidth = FALSE,
    notch = FALSE, outline = TRUE, names, plot = TRUE, border = par("fg"),
    col = NULL, log = "", pars = list(boxwex = 0.8, staplewex = 0.5,
        outwex = 0.5), horizontal = FALSE, add = FALSE, at = NULL)
{
    args <- list(x, ...)
    namedargs <- if (!is.null(attributes(args)$names))
        attributes(args)$names != ""
    else rep(FALSE, length.out = length(args))
    groups <- if (is.list(x))
        x
    else args[!namedargs]
    if (0 == (n <- length(groups)))
        stop("invalid first argument")
    if (length(class(groups)))
        groups <- unclass(groups)
    if (!missing(names))
        attr(groups, "names") <- names
    else {
        if (is.null(attr(groups, "names")))
            attr(groups, "names") <- 1:n
        names <- attr(groups, "names")
    }
    cls <- sapply(groups, function(x) class(x)[1])
    cl <- if (all(cls == cls[1]))
        cls[1]
    else NULL
    for (i in 1:n) groups[i] <- list(boxplot2.stats(unclass(groups[[i]]),
        range))
    stats <- matrix(0, nrow = 5, ncol = n)
    conf <- matrix(0, nrow = 2, ncol = n)
    ng <- out <- group <- numeric(0)
    ct <- 1
    for (i in groups) {
        stats[, ct] <- i$stats
        conf[, ct] <- i$conf
        ng <- c(ng, i$n)
        if ((lo <- length(i$out))) {
            out <- c(out, i$out)
            group <- c(group, rep.int(ct, lo))
        }
        ct <- ct + 1
    }
    if (length(cl) && cl != "numeric")
        oldClass(stats) <- cl
    z <- list(stats = stats, n = ng, conf = conf, out = out,
        group = group, names = names)
    if (plot) {
        if (is.null(pars$boxfill) && is.null(args$boxfill))
            pars$boxfill <- col
        do.call("bxp", c(list(z, notch = notch, width = width,
            varwidth = varwidth, log = log, border = border,
            pars = pars, outline = outline, horizontal = horizontal,
            add = add, at = at), args[namedargs]))
        invisible(z)
    }
    else z
}
boxplot2.formula <- function (formula, data = NULL, ..., subset, na.action = NULL)
{
    if (missing(formula) || (length(formula) != 3))
        stop("'formula' missing or incorrect")
    m <- match.call(expand.dots = FALSE)
    if (is.matrix(eval(m$data, parent.frame())))
        m$data <- as.data.frame(data)
    m$... <- NULL
    m$na.action <- na.action
    require(stats, quietly = TRUE)
    m[[1]] <- as.name("model.frame")
    mf <- eval(m, parent.frame())
    response <- attr(attr(mf, "terms"), "response")
    boxplot2(split(mf[[response]], mf[-response]), ...)
}

boxplot2.stats <- function (x, coef = 1.5, do.conf = TRUE, do.out = TRUE)
{
    if (coef < 0)
        stop("'coef' must not be negative")
    nna <- !is.na(x)
    n <- sum(nna)
    stats <- stats::fivenum(x, na.rm = TRUE)
    iqr <- diff(stats[c(2, 4)])
    if (coef == 0)
        do.out <- FALSE
    else {
        out <- if (!is.na(iqr)) {
            x < (stats[2] - coef * iqr) | x > (stats[4] + coef *
                iqr)
        }
        else !is.finite(x)
        if (any(out[nna], na.rm = TRUE))
            stats[c(1, 5)] <- range(x[!out], na.rm = TRUE)
    }
    conf <- if (do.conf)
        stats[3] + c(-1.58, 1.58) * iqr/sqrt(n)
    stats[c(2,4)] <- quantile(x,c(0.05,0.95))
    list(stats = stats, n = n, conf = conf, out = if (do.out) x[out &
        nna] else numeric(0))
}


Un petit exemple :

Code : Tout sélectionner

x <- rnorm(100)
boxplot2(x)
abline(h=quantile(x,c(0.05,0.95)))


Ici l'écart entre les bords des boites et les intervalles n'as plus de trop de sens.


Maxime

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 24 Nov 2008, 18:48

Je vais a fond dans le sens de Maxime : dans ma fac, certains prof estime que les valeurs adhérentes surpérieures et inférieures, c'est trop compliqué et donc ils "simplifient" en faisant des boites 5% - 25% - 50% - 75% - 95%. Mais ca n'est PLUS des boites a moustache. En particulier, une boite a moustache peut tres bien considérer qu'il n'y a pas de valeur extrêmes (par exemple boxplot(1:20) )Par contre, la "fausse" boite trouvera toujours des valeurs extrêmes, même dans les cas ou toutes les données sont gentiment regroupées...

C.

Julie LEGER
Messages : 3
Enregistré le : 21 Nov 2008, 17:03

Messagepar Julie LEGER » 24 Nov 2008, 21:53

Je vous remercie pour vos réponses.
Effectivement, après observation plus approfondie de mes données et quelques box-plot 5%-25%-50%-75%-95%, je me suis rendue compte que cette vision des choses n'était pas la bonne.
En tout cas je vous remercie encore de votre aide.
Ju

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 24 Nov 2008, 22:08

Julie LEGER a écrit :Je vous remercie pour vos réponses.
Effectivement, après observation plus approfondie de mes données et quelques box-plot 5%-25%-50%-75%-95%, je me suis rendue compte que cette vision des choses n'était pas la bonne.
En tout cas je vous remercie encore de votre aide.
Ju

Tiens, si tu veux plus de détails sur l'art et manière de construire une boite à moustache, j'avais fait un petit tutorial pour mes étudiants : http://christophe.genolini.free.fr/aTel ... oxplot.pdf

Julie LEGER
Messages : 3
Enregistré le : 21 Nov 2008, 17:03

Messagepar Julie LEGER » 25 Nov 2008, 07:19

Merci.
Ju

jean lobry
Messages : 733
Enregistré le : 17 Jan 2008, 20:00
Contact :

Messagepar jean lobry » 25 Nov 2008, 10:47

Bonjour,

il n'y a bien qu'en France où l'on puisse imaginer que les boîtes à moustaches puissent être normalisées : http://mathazay.free.fr/spip.php?article495. Voir aussi http://mathazay.free.fr/spip.php?action=autoriser&arg=192.

Quand on demandé à John Tukey (l'inventeur du boxplot) pourquoi il utilisait 1.5 fois l'écart inter-quartilles il a répondu quelque chose du genre : ben parce que 1 c'est trop petit et 2 c'est trop grand.

Amicalement,

Jean

Renaud Lancelot
Messages : 2484
Enregistré le : 16 Déc 2004, 08:01
Contact :

Messagepar Renaud Lancelot » 30 Nov 2008, 20:18

J'ai aussi entendu dire que si la variable étudiée a une distribution normale, l'intervalle entre les extrémités des moustaches comporte approximativement 95% des valeurs. Pas eu le courage de vérifier...

Renaud

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 30 Nov 2008, 22:14

Renaud Lancelot a écrit :J'ai aussi entendu dire que si la variable étudiée a une distribution normale, l'intervalle entre les extrémités des moustaches comporte approximativement 95% des valeurs.

Intéressant
Pas eu le courage de vérifier...

Tsssss...
;-)

Allez, pour une fois que je peux répondre a un truc facile...

Alors :

Code : Tout sélectionner

### Q1, Q3 et l'espace inter quartile :
Q1 <- qnorm(0.25)
Q3 <- qnorm(0.75)
(intQ3Q1 <- Q3-Q1)
# [1] 1.348980
 
### adhérences inf et sup
(adSup <- Q3+1.5*intQ3Q1)
# [1] 2.697959
(adInf <- Q1-1.5*intQ3Q1)
# [1] -2.697959

### Pourcentage non compris entre adInf et adSup :
(pnorm(adSup)-pnorm(adInf))
# [1] 0.9930234


Sauf erreur de ma part, l'intervalle entre les moustaches contient 99.3% des valeurs.
Perdu :-(
En un sens, c'est dommage, ça aurait été un résultat sympa.

D'un autre côté, heureusement parce que si je ne me trompe pas, les moustaches servent plus ou moins à détecter les aberrations. Or 5% d'aberrations, ça ferait tout de même beaucoup...


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité