Me gustaría eliminar las líneas en este marco de datos que:
a) contienen NA
s en todas las columnas. A continuación se muestra mi marco de datos de ejemplo.
gene hsap mmul mmus rnor cfam
1 ENSG00000208234 0 NA NA NA NA
2 ENSG00000199674 0 2 2 2 2
3 ENSG00000221622 0 NA NA NA NA
4 ENSG00000207604 0 NA NA 1 2
5 ENSG00000207431 0 NA NA NA NA
6 ENSG00000221312 0 1 2 3 2
Básicamente, me gustaría obtener un marco de datos como el siguiente.
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
6 ENSG00000221312 0 1 2 3 2
b) contiene NA
s solo en algunas columnas , por lo que también puedo obtener este resultado:
gene hsap mmul mmus rnor cfam
2 ENSG00000199674 0 2 2 2 2
4 ENSG00000207604 0 NA NA 1 2
6 ENSG00000221312 0 1 2 3 2
final[complete.cases(final),]
?complete.cases
? ¿Si quisiera mantener las filas con NA en lugar de descartarlas?final[ ! complete.cases(final),]
no coopera ...final
¿Es variable el marco de datos?Tratar
na.omit(your.data.frame)
. En cuanto a la segunda pregunta, intente publicarla como otra pregunta (para mayor claridad).fuente
rownames(x) <- NULL
.na.omit()
suelta las filas que contienenNA
en cualquier columnatidyr
tiene una nueva funcióndrop_na
:fuente
drop_na
. Por ejemplo,df %>% drop_na()
,df %>% na.omit()
ydrop_na(df)
son básicamente equivalentes.na.omit
agrega información adicional, como los índices de casos omitidos, y, lo que es más importante, no le permite seleccionar columnas, aquí es dondedrop_na
brilla.na.omit
con o sin tuberías, tal como puede usardrop_na
con o sin tuberías.Prefiero la siguiente forma de verificar si las filas contienen NA:
Esto devuelve un vector lógico con valores que indican si hay NA en una fila. Puede usarlo para ver cuántas filas tendrá que soltar:
y finalmente dejarlos caer
Para filtrar filas con cierta parte de NA, se vuelve un poco más complicado (por ejemplo, puede alimentar 'final [, 5: 6]' para 'aplicar'). En general, la solución de Joris Meys parece ser más elegante.
fuente
rowSum(!is.na(final))
parece más adecuado queapply()
Otra opción si desea un mayor control sobre cómo las filas se consideran no válidas es
Usando lo anterior, esto:
Se convierte en:
... donde solo se elimina la fila 5, ya que es la única fila que contiene NA para ambos
rnor
ANDcfam
. La lógica booleana se puede cambiar para adaptarse a requisitos específicos.fuente
Si desea controlar cuántos NA son válidos para cada fila, pruebe esta función. Para muchos conjuntos de datos de encuestas, demasiadas respuestas de preguntas en blanco pueden arruinar los resultados. Por lo tanto, se eliminan después de un cierto umbral. Esta función le permitirá elegir cuántos NA puede tener la fila antes de que se elimine:
Por defecto, eliminará todas las NA:
O especifique el número máximo de NA permitido:
fuente
Si el rendimiento es una prioridad, use
data.table
yna.omit()
con param opcionalcols=
.na.omit.data.table
es el más rápido en mi punto de referencia (ver más abajo), ya sea para todas las columnas o para columnas seleccionadas (pregunta OP, parte 2).Si no quiere usar
data.table
, usecomplete.cases()
.En una vainilla
data.frame
,complete.cases
es más rápido quena.omit()
odplyr::drop_na()
. Tenga en cuenta quena.omit.data.frame
no es compatiblecols=
.Resultado de referencia
Aquí hay una comparación de los métodos base (azul),
dplyr
(rosa) ydata.table
(amarillo) para descartar todas o seleccionar las observaciones faltantes, en un conjunto de datos nocionales de 1 millón de observaciones de 20 variables numéricas con un 5% de probabilidad de que falten, y un subconjunto de 4 variables para la parte 2.Sus resultados pueden variar según la longitud, el ancho y la escasez de su conjunto de datos en particular.
Observe la escala logarítmica en el eje y.
Script de referencia
fuente
Usando el paquete dplyr podemos filtrar NA de la siguiente manera:
fuente
drop_na()
Esto devolverá las filas que tienen al menos UN valor no NA.
Esto devolverá las filas que tienen al menos DOS valores no NA.
fuente
Para su primera pregunta, tengo un código con el que me siento cómodo para deshacerme de todas las NA. Gracias por @Gregor para hacerlo más simple.
Para la segunda pregunta, el código es solo una alternancia de la solución anterior.
Observe que -5 es el número de columnas en sus datos. Esto eliminará las filas con todos los NA, ya que rowSums suma hasta 5 y se convierten en ceros después de la resta. Esta vez, as.logical es necesario.
fuente
También podemos usar la función de subconjunto para esto.
Esto dará solo aquellas filas que no tienen NA en mmul y rnor
fuente
Soy un sintetizador :). Aquí combiné las respuestas en una función:
fuente
Asumiendo
dat
como su marco de datos, la salida esperada se puede lograr usando1)
rowSums
2)
lapply
fuente
Uno de los enfoques que a la vez general y produce bastante código legible es utilizar la
filter
función y sus variantes en el paquete (dplyrfilter_all
,filter_at
,filter_if
):fuente
La función anterior elimina todas las filas del marco de datos que tiene 'NA' en cualquier columna y devuelve los datos resultantes. Si desea verificar múltiples valores como
NA
y?
cambiardart=c('NA')
en la función param adart=c('NA', '?')
fuente
Supongo que esto podría resolverse de manera más elegante de esta manera:
fuente
NA
. Creo que lo que quiere el OP es:df %>% filter_all(all_vars(!is.na(.)))