Come rimuovere valori anomali da un set di dati
-
24-10-2019 - |
Domanda
Ho alcuni dati multivariati di bellezza vs età. Le età vanno 20-40 ad intervalli di 2 (20, 22, 24 .... 40), e per ogni record di dati, sono dati un'età e un rating bellezza 1-5. Quando faccio i grafici a scatole di questi dati (età in tutto l'asse X, valutazioni di bellezza in tutto l'asse Y), ci sono alcuni valori anomali tracciati al di fuori dei baffi di ogni casella.
voglio rimuovere questi valori anomali dal frame di dati in sé, ma non sono sicuro di come R calcola valori anomali per le sue trame box. Di seguito è riportato un esempio di ciò che i miei dati potrebbe essere simile.
Soluzione
OK, si dovrebbe applicare qualcosa di simile per il set di dati. Non sostituire & salvare o si distruggerà i vostri dati! E, a proposito, è necessario (quasi) mai rimuovere valori anomali dai dati:
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
}
Per vederlo in azione:
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()
E ancora una volta, non si dovrebbe mai fare da soli, i valori anomali sono solo scopo di essere! =)
Modifica ho aggiunto na.rm = TRUE
come predefinito
EDIT2: la funzione quantile
rimossi, subscripting aggiunto, quindi ha fatto la funzione più veloce! =)
Altri suggerimenti
Nessuno ha pubblicato la risposta più semplice:
x[!x %in% boxplot.stats(x)$out]
Si veda anche questo: http: //www.r-statistics.com/2011/01/how-to-label-all-the-outliers-in-a-boxplot/
Usa outline = FALSE
come opzione quando si fa il grafico a scatole (leggi l'aiuto!).
> m <- c(rnorm(10),5,10)
> bp <- boxplot(m, outline = FALSE)
I ritorni di funzione grafico a scatole dei valori usati per fare il tracciato (che in realtà è poi fatto da 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
ho volutamente non ha risposto alla domanda specifica, perché ritengo malcostume statistico rimuovere "valori anomali". Ritengo pratica accettabile di non tracciare loro in un grafico a scatole, ma rimuovendoli solo perché superano un certo numero di deviazioni standard o di un determinato numero di larghezza inter-quartile è una storpiatura sistematica e non scientifica del record di osservazione.
x<-quantile(retentiondata$sum_dec_incr,c(0.01,0.99))
data_clean <- data[data$attribute >=x[1] & data$attribute<=x[2],]
Trovo questo molto facile da rimuovere valori anomali. Nell'esempio sopra sto solo estrazione 2 percentile al 98 percentile di valori di attributi.
I alzò gli occhi per i pacchetti relativi alla rimozione di valori anomali, e ha trovato questo pacchetto (sorprendentemente chiamati "valori anomali"!): https://cran.r-project.org/web/packages/outliers/outliers.pdf
se si va attraverso di essa che si vede diversi modi di rimozione di valori anomali e fra li ho trovati rm.outlier
più conveniente quello per l'uso e, come si dice nel link qui sopra:
"Se viene rilevato e confermato da test statistici il valore anomalo, questa funzione può rimuovere o sostituire
media campione o mediana" e anche qui è la parte di utilizzo dalla stessa fonte:
" Utilizzo
rm.outlier(x, fill = FALSE, median = FALSE, opposite = FALSE)
Argomenti
x un set di dati, più frequentemente un vettore. Se l'argomento è un dataframe, allora è outlier
rimosso da ogni colonna sapply. Lo stesso comportamento viene applicata da applicare
quando viene dato il matrice.
di riempimento se impostato su true, la mediana o media è collocato al posto del valore anomalo. In caso contrario, il
outlier (s) è / sono semplicemente rimossi.
mediano se impostato su true, mediano è usato al posto di media in outlier sostituzione.
opposto se impostato su TRUE, dà valore opposto (se valore più grande ha la massima differenza
dalla media, dà più piccolo e viceversa)
"
Non sarebbe:
z <- df[df$x > quantile(df$x, .25) - 1.5*IQR(df$x) &
df$x < quantile(df$x, .75) + 1.5*IQR(df$x), ] #rows
eseguire questa operazione abbastanza facilmente?
L'aggiunta alla suggestione @sefarkas' e l'utilizzo di quantile come cut-off, si potrebbe esplorare la seguente opzione:
newdata <- subset(mydata,!(mydata$var > quantile(mydata$var, probs=c(.01, .99))[2] | mydata$var < quantile(mydata$var, probs=c(.01, .99))[1]) )
Questo consente di eliminare i punti di punti al di là del 99 ° quantile. Si deve prestare attenzione come quello che stava dicendo aL3Xa su valori anomali di conservazione. Deve essere rimosso solo per ottenere una visione conservatrice alternativa dei dati.
Prova questo. Nutrire la variabile nella funzione e salva l'O / P nella variabile che conterrebbe i valori anomali rimossi
outliers<-function(variable){
iqr<-IQR(variable)
q1<-as.numeric(quantile(variable,0.25))
q3<-as.numeric(quantile(variable,0.75))
mild_low<-q1-(1.5*iqr)
mild_high<-q3+(1.5*iqr)
new_variable<-variable[variable>mild_low & variable<mild_high]
return(new_variable)
}