108 votes

Comment supprimer les valeurs aberrantes d'un ensemble de données ?

J'ai des données multivariées sur la beauté en fonction de l'âge. Les âges vont de 20 à 40 ans à des intervalles de 2 (20, 22, 24....40), et pour chaque enregistrement de données, on leur donne un âge et une note de beauté de 1 à 5. Lorsque je fais des boxplots de ces données (âges sur l'axe des X, notes de beauté sur l'axe des Y), il y a quelques valeurs aberrantes tracées en dehors des moustaches de chaque boîte.

Je veux supprimer ces valeurs aberrantes du cadre de données lui-même, mais je ne sais pas comment R calcule les valeurs aberrantes pour ses diagrammes en boîte. Voici un exemple de ce à quoi mes données pourraient ressembler. enter image description here

2 votes

Le site boxplot renvoie les valeurs aberrantes (entre autres statistiques) de manière invisible. Essayez foo <- boxplot(...); foo et lire ?boxplot pour comprendre la sortie.

0 votes

Vous devriez modifier votre question en fonction du commentaire que vous avez fait sur la réponse de @Prasad !

0 votes

@aL3xa : c'est dans la première phrase du deuxième paragraphe.

151voto

J. Winchester Points 1999

Personne n'a posté la réponse la plus simple :

x[!x %in% boxplot.stats(x)$out]

Voir aussi ceci : http://www.r-statistics.com/2011/01/how-to-label-all-the-outliers-in-a-boxplot/

4 votes

Vraiment élégant. Merci. Mais il faut faire attention si la distribution a plus d'un mode et si les valeurs aberrantes sont effectivement peu nombreuses et dispersées.

0 votes

Il aurait été formidable que vous puissiez les indexer dans un ensemble de données. La façon dont vous procédez filtrera en fonction de la valeur des données. Si le box plot fait aussi du regroupement, ce ne sera pas forcément la même valeur de données qui sera aberrante dans chaque groupe.

3 votes

Il est également important de mentionner que cela ne modifie pas l'ensemble des données. Il s'agit simplement d'une méthode de filtrage. Donc, si vous avez l'intention d'utiliser l'ensemble de données sans valeurs aberrantes, attribuez-le à une variable, par ex. result = x[!x %in% boxplot.stats(x)$out]

130voto

aL3xa Points 10236

OK, vous devriez appliquer quelque chose comme ça à votre jeu de données. Ne remplacez pas & sauvegardez ou vous détruirez vos données ! Et, au fait, vous ne devriez (presque) jamais supprimer les valeurs aberrantes de vos données :

remove_outliers <- function(x, na.rm = TRUE, ...) {
  qnt <- quantile(x, probs=c(.25, .75), na.rm = na.rm, ...)
  H <- 1.5 * IQR(x, na.rm = na.rm)
  y <- x
  y[x < (qnt[1] - H)] <- NA
  y[x > (qnt[2] + H)] <- NA
  y
}

Pour le voir en action :

set.seed(1)
x <- rnorm(100)
x <- c(-10, x, 10)
y <- remove_outliers(x)
## png()
par(mfrow = c(1, 2))
boxplot(x)
boxplot(y)
## dev.off()

Et encore une fois, vous ne devriez jamais faire cela tout seul, les valeurs aberrantes sont juste faites pour être ! =)

EDIT : J'ai ajouté na.rm = TRUE par défaut.

EDIT2 : Supprimé quantile a ajouté des indices, ce qui a rendu la fonction plus rapide ! =)

enter image description here

0 votes

Merci pour votre aide ! Je pense que si R est capable d'afficher les valeurs aberrantes dans un boxplot, je ne devrais pas avoir à faire ces calculs intermédiaires. Quant à la suppression des valeurs aberrantes, c'est juste pour un devoir.

3 votes

OK, il y a quelque chose qui m'échappe. Vous voulez supprimer les valeurs aberrantes des données, afin de pouvoir les tracer avec boxplot . C'est gérable, et vous devriez alors marquer la réponse de @Prasad, qui a répondu à votre question. Si vous voulez exclure les valeurs aberrantes en utilisant la "règle des valeurs aberrantes" q +/- (1.5 * H) et donc effectuer une analyse, puis utiliser cette fonction. En outre, j'ai fait cela à partir de rien, sans chercher sur Google, il est donc possible que j'aie réinventé la roue avec cette fonction...

10 votes

Vous ne devriez pas poser des questions d'affectation sur stackoverflow !

32voto

Prasad Chalasani Points 9020

Utilisez outline = FALSE comme option lorsque vous faites le boxplot (lisez l'aide !).

> m <- c(rnorm(10),5,10)
> bp <- boxplot(m, outline = FALSE)

enter image description here

4 votes

En effet, cela supprimera les valeurs aberrantes du boxplot lui-même, mais je veux supprimer les valeurs aberrantes du cadre de données.

2 votes

Je vois, alors comme @Joshua l'a dit, vous devez examiner les données renvoyées par la fonction boxplot (en particulier la fonction out et group éléments de la liste).

17voto

BondedDust Points 105234

La fonction boxplot renvoie les valeurs utilisées pour réaliser le tracé (qui est en fait réalisé par bxp()) :

bstats <- boxplot(count ~ spray, data = InsectSprays, col = "lightgray") 
#need to "waste" this plot
bstats$out <- NULL
bstats$group <- NULL
bxp(bstats)  # this will plot without any outlier points

Je n'ai volontairement pas répondu à la question spécifique parce que je considère que la suppression des "valeurs aberrantes" est une faute professionnelle statistique. Je considère comme une pratique acceptable le fait de ne pas les tracer dans un boxplot, mais les supprimer est une manipulation systématique et injustifiée des données d'observation.

5 votes

Et bien, éluder la question sans savoir pourquoi elle a été posée n'est pas non plus une bonne pratique. Oui, il n'est pas bon de supprimer les "valeurs aberrantes" des données, mais il arrive que l'on ait besoin de données sans valeurs aberrantes pour des tâches spécifiques. Dans un devoir de statistiques que j'ai eu récemment, nous devions visualiser un ensemble sans ses valeurs aberrantes afin de déterminer le meilleur modèle de régression à utiliser pour les données. Voilà !

4 votes

Je ne considère pas que les conseils que vous avez pu recevoir à cet égard pour "déterminer le meilleur modèle de régression" soient particulièrement convaincants. Au contraire, si vous avez eu besoin de supprimer les valeurs aberrantes dans ce but vaguement déclaré, alors je pense que cela reflète mal les personnes qui vous ont conseillé plutôt que d'être une preuve de l'invalidité de ma position.

0 votes

Je suppose que c'est légitime quand on sait qu'on élimine le "bruit", surtout dans les données physiologiques.

-1voto

sefarkas Points 11

La fonction subset( ) est le moyen le plus simple de sélectionner les variables et l'observation. Dans l'exemple suivant, nous sélectionnons toutes les lignes qui ont une valeur d'âge supérieure ou égale à 20 ou un âge inférieur à 10. Nous conservons les colonnes ID et Weight.

# using subset function

newdata <- subset(mydata, age >= 20 | age < 10, select=c(ID, Weight))

Dans l'exemple suivant, nous sélectionnons tous les hommes âgés de plus de 25 ans et nous conservons les variables poids à revenu (poids, revenu et toutes les colonnes entre elles).

# using subset function (part 2)
newdata <- subset(mydata, sex=="m" & age > 25,
select=weight:income)

Méthodes supplémentaires à http://www.statmethods.net/management/subset.html

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