Cómo eliminar valores atípicos de un conjunto de datos


98

Tengo algunos datos multivariados de belleza frente a edades. Las edades van de 20 a 40 a intervalos de 2 (20, 22, 24 ... 40), y para cada registro de datos, se les asigna una edad y una calificación de belleza de 1 a 5. Cuando hago diagramas de caja de estos datos (edades en el eje X, calificaciones de belleza en el eje Y), hay algunos valores atípicos trazados fuera de los bigotes de cada caja.

Quiero eliminar estos valores atípicos del marco de datos en sí, pero no estoy seguro de cómo R calcula los valores atípicos para sus diagramas de caja. A continuación se muestra un ejemplo de cómo podrían verse mis datos. ingrese la descripción de la imagen aquí


2
La boxplotfunción devuelve los valores atípicos (entre otras estadísticas) de forma invisible. Intente foo <- boxplot(...); fooleer ?boxplotpara comprender el resultado.
Joshua Ulrich

¡Debe editar su pregunta de acuerdo con el comentario que dio sobre la respuesta de @ Prasad!
aL3xa

@ aL3xa: está en la primera oración del segundo párrafo.
Joshua Ulrich


¿Puede enviar un enlace a los datos?
wordsforthewise

Respuestas:


119

Bien, deberías aplicar algo como esto a tu conjunto de datos. ¡No reemplace ni guarde o destruirá sus datos! Y, por cierto, (casi) nunca debe eliminar los valores atípicos de sus datos:

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
}

Para verlo en acción:

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()

Y una vez más, nunca debe hacer esto por su cuenta, ¡los valores atípicos están destinados a ser! =)

EDITAR: agregué na.rm = TRUEpor defecto.

EDIT2:quantile función eliminada , subíndice agregado, ¡por lo tanto, hizo que la función sea más rápida! =)

ingrese la descripción de la imagen aquí


¡Gracias por la ayuda! Creo que si R es capaz de generar los valores atípicos en el diagrama de caja, no debería tener que hacer estos cálculos intermedios. En cuanto a la eliminación de valores atípicos, esto es solo para una tarea.
Dan Q

3
Bien, me falta algo aquí. Desea eliminar los valores atípicos de los datos para poder trazarlos con boxplot. Eso es manejable, y debe marcar la respuesta de @ Prasad entonces, ya que respondió a su pregunta. Si desea excluir valores atípicos mediante el uso de una "regla de valores atípicos" q +/- (1.5 * H), ejecute un análisis y utilice esta función. Por cierto, hice esto desde cero, sin buscar en Google, así que existe la posibilidad de que haya reinventado la rueda con esta función mía ...
aL3xa

10
¡No debería hacer preguntas sobre tareas en stackoverflow!
hadley

7
¿Significa eso que tampoco deberíamos responder? =)
aL3xa

5
"Los valores atípicos están destinados a ser"? No necesariamente. Pueden provenir de errores de medición y deben revisarse minuciosamente. Cuando el valor atípico es demasiado grande, puede significar algo o no tanto. Por eso (al menos en biología) la mediana suele decir más sobre una población que la media.
Rodrigo

132

Nadie ha publicado la respuesta más simple:

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

Vea también esto: http://www.r-statistics.com/2011/01/how-to-label-all-the-outliers-in-a-boxplot/


4
Realmente elegante. Gracias. Pero hay que tener cuidado si la distribución tiene más de un modo y los valores atípicos son, de hecho, pocos y están dispersos.
KarthikS

Hubiera sido genial si pudiera obtener un índice de ellos en un conjunto de datos. La forma en que haya terminado se filtrará según el valor de los datos. Si el diagrama de caja también está agrupando, no necesariamente el mismo valor de datos será atípico en cada grupo
adam

2
También es importante mencionar que no cambia el conjunto de datos. Este es solo un método de filtrado. Entonces, si tiene la intención de usar el conjunto de datos sin valores atípicos, asígnelo a una variable. Ej .result = x[!x %in% boxplot.stats(x)$out]
Victor Augusto

Tener solo una línea de código no significa necesariamente que sea simple. No siempre es fácil de entender un código de una línea, especialmente para principiantes y sin comentarios.
PeyM87

29

Úselo outline = FALSEcomo una opción cuando haga el diagrama de caja (¡lea la ayuda!)

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

ingrese la descripción de la imagen aquí


4
de hecho, esto eliminará los valores atípicos del diagrama de caja, pero quiero eliminar los valores atípicos del marco de datos.
Dan Q

2
Ya veo, entonces, como dijo @Joshua, debe mirar los datos devueltos por la función boxplot (en particular, los elementos outy groupen la lista).
Prasad Chalasani

16

La función de diagrama de caja devuelve los valores utilizados para realizar el trazado (que en realidad se realiza mediante 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

A propósito, no respondí a la pregunta específica porque considero que eliminar los "valores atípicos" es una mala práctica estadística. Considero que es una práctica aceptable no trazarlos en un diagrama de caja, pero eliminarlos solo porque exceden cierto número de desviaciones estándar o cierto número de anchos intercuartiles es una alteración sistemática y poco científica del registro de observación.


4
Bueno, eludir la pregunta sin saber por qué se hizo la pregunta tampoco es una buena práctica. Sí, no es bueno eliminar "valores atípicos" de los datos, pero a veces necesita los datos sin valores atípicos para tareas específicas. En una asignación de estadística que tuve recientemente, tuvimos que visualizar un conjunto sin sus valores atípicos para determinar el mejor modelo de regresión para usar con los datos. ¡Por lo tanto, allí!
Alex Essilfie

4
No estoy considerando el consejo que puede haber recibido en este sentido para "determinar el mejor modelo de regresión" para ser particularmente persuasivo. En cambio, si necesita eliminar los valores atípicos para ese propósito vagamente establecido, creo que se refleja mal en las personas que lo aconsejaron en lugar de ser una prueba de la invalidez de mi cargo.
IRTFM

Supongo que es legítimo cuando sabes que estás eliminando el "ruido". especialmente en datos fisiológicos.
roscoe1895

Si. Si tiene una buena razón para creer que un proceso separado crea la señal, es una justificación para la eliminación de los datos.
IRTFM

9

Busqué paquetes relacionados con la eliminación de valores atípicos y encontré este paquete (¡sorprendentemente llamado "outliers"!): Https://cran.r-project.org/web/packages/outliers/outliers.pdf
si lo revisa, vea diferentes formas de eliminar valores atípicos y entre ellos encontré la rm.outliermás conveniente de usar y, como dice en el enlace anterior: "Si el valor atípico se detecta y confirma mediante pruebas estadísticas, esta función puede eliminarlo o reemplazarlo por la media o mediana de la muestra" y también aquí está la parte de uso de la misma fuente:
" Uso

rm.outlier(x, fill = FALSE, median = FALSE, opposite = FALSE)

Argumentos
x un conjunto de datos, con mayor frecuencia un vector. Si el argumento es un marco de datos, sapply elimina los valores atípicos de cada columna. El mismo comportamiento se aplica aplicando cuando se da la matriz.
llenar Si se establece en VERDADERO, la mediana o media se coloca en lugar de un valor atípico. De lo contrario, los valores atípicos simplemente se eliminan.
mediana Si se establece en VERDADERO, se usa la mediana en lugar de la media en el reemplazo de valores atípicos. opuesto si se establece en VERDADERO, da el valor opuesto (si el valor más grande tiene la diferencia máxima de la media, da el más pequeño y viceversa) "


Esto parece genial, pero si tiene una columna de serie de tiempo en su marco de datos, cambia la serie de tiempo.
PeyM87

7
x<-quantile(retentiondata$sum_dec_incr,c(0.01,0.99))
data_clean <- data[data$attribute >=x[1] & data$attribute<=x[2],]

Encuentro esto muy fácil de eliminar los valores atípicos. En el ejemplo anterior, solo estoy extrayendo del percentil 2 al percentil 98 de los valores de los atributos.


5

No lo haría:

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

realizar esta tarea con bastante facilidad?


4

Agregando a la sugerencia de @sefarkas y usando cuantil como puntos de corte, se podría explorar la siguiente opción:

newdata <- subset(mydata,!(mydata$var > quantile(mydata$var, probs=c(.01, .99))[2] | mydata$var < quantile(mydata$var, probs=c(.01, .99))[1]) ) 

Esto eliminará los puntos más allá del cuantil 99. Se debe tener cuidado como lo que decía aL3Xa acerca de mantener valores atípicos. Debe eliminarse solo para obtener una vista conservadora alternativa de los datos.


es 0.91o 0.99? como en mydata$var < quantile(mydata$var, probs=c(.01, .91))[1])omydata$var < quantile(mydata$var, probs=c(.01, .99))[1])
Komal Rathi

Si tiene una razón específica para usar el percentil 91 en lugar del percentil 99, puede usarlo. Es solo una heurística
KarthikS

1

1 forma de hacerlo es

my.NEW.data.frame <- my.data.frame[-boxplot.stats(my.data.frame$my.column)$out, ]

o

my.high.value <- which(my.data.frame$age > 200 | my.data.frame$age < 0) 
my.NEW.data.frame <- my.data.frame[-my.high.value, ]

0

Los valores atípicos son bastante similares a los picos, por lo que un detector de picos puede ser útil para identificar valores atípicos. El método descrito aquí tiene un rendimiento bastante bueno usando puntuaciones z. La animación en la parte inferior de la página ilustra el método que señala valores atípicos o picos.

Los picos no siempre son los mismos que los valores atípicos, pero son similares con frecuencia.

A continuación se muestra un ejemplo: este conjunto de datos se lee desde un sensor a través de comunicaciones en serie. Los errores ocasionales de comunicación en serie, errores del sensor o ambos conducen a puntos de datos repetidos y claramente erróneos. No hay valor estadístico en estos puntos. Podría decirse que no son valores atípicos, son errores. El detector de picos de puntuación z pudo señalar en puntos de datos falsos y generó un conjunto de datos resultante limpio:ingrese la descripción de la imagen aquí


-1

Prueba esto. Alimente su variable en la función y guarde el o / p en la variable que contendría valores atípicos eliminados

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

Agregue alguna explicación a su respuesta. Consulte Cómo responder .
ejderuby
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.