Subconjunto de filas que contienen valores NA (faltantes) en una columna elegida de un marco de datos

96

Tenemos un marco de datos de un archivo CSV. El marco de datos DFtiene columnas que contienen valores observados y una columna ( VaR2) que contiene la fecha en la que se tomó una medición. Si no se registró la fecha, el archivo CSV contiene el valor NAde los datos faltantes.

Var1  Var2 
10   2010/01/01
20   NA
30   2010/03/01

Nos gustaría usar el comando subconjunto para definir un nuevo marco de datos de new_DFmanera que solo contenga filas que tengan un NA'valor de la columna ( VaR2). En el ejemplo dado, solo la Fila 2 estará contenida en el nuevoDF .

El comando

new_DF<-subset(DF,DF$Var2=="NA") 

no funciona, el marco de datos resultante no tiene entradas de fila.

Si en el archivo CSV original NAse intercambia el Valor NULL, el mismo comando produce el resultado deseado:new_DF<-subset(DF,DF$Var2=="NULL") .

¿Cómo puedo hacer que este método funcione, si para la cadena de caracteres el valor NAse proporciona en el archivo CSV original?

Juan
fuente

Respuestas:

147

Nunca use == 'NA' para probar los valores perdidos. Úselo en su is.na()lugar. Esto debería hacerlo:

new_DF <- DF[rowSums(is.na(DF)) > 0,]

o en caso de que desee verificar una columna en particular, también puede usar

new_DF <- DF[is.na(DF$Var),]

En caso de que tenga valores de caracteres NA, primero ejecute

Df[Df=='NA'] <- NA

para reemplazarlos con valores perdidos.

Joris Meys
fuente
2
¡Gracias por su rápida respuesta (esto fue rápido)! De hecho, debido a la entrega csv de los datos, los 'NA' son valores de caracteres y su segunda declaración podría ser muy útil. ¿Puede aclarar también su primera afirmación? El uso de rowSums () no está claro para mí, ya que solo verificaré una columna en particular (hay muchas columnas). Si esa columna en particular (en el ejemplo sería la columna Var2) tiene una cadena de caracteres 'NA' (la reemplazaré con su segunda declaración), entonces me gustaría elegir la fila completa para que sea parte del nuevo marco de datos .
Juan
@John: actualizado. El punto es usar is.na, interpreté erróneamente que quería verificar todas las variables.
Joris Meys
3
¿Debería ser así new_DF <- DF[is.na(DF$Var),], es decir, parece haber un (paréntesis adicional después DF[?
PatrickT
39

NA es un valor especial en R, no mezcle el valor NA con la cadena "NA". Dependiendo de la forma en que se importaron los datos, sus celdas "NA" y "NULL" pueden ser de varios tipos (el comportamiento predeterminado es convertir cadenas "NA" en valores NA y dejar cadenas "NULL" como están).

Si usa read.table () o read.csv (), debe considerar el argumento "na.strings" para realizar una importación de datos limpia y trabajar siempre con valores reales de R NA.

Un ejemplo, trabajando en ambos casos celdas "NULL" y "NA":

DF <- read.csv("file.csv", na.strings=c("NA", "NULL"))
new_DF <- subset(DF, is.na(DF$Var2))
maressyl
fuente
1
Gracias por tu respuesta. Si lo entiendo correctamente, la primera declaración haría lo mismo que Df [Df == 'NA'] <- NA en el ejemplo de Joris? La (pequeña) diferencia entonces sería que se hace en su declaración directamente al principio, cuando se crea el marco de datos (este es un método de programación muy limpio y, por lo tanto, me gusta).
Juan
Exactamente. Joris sugirió reemplazar las cadenas "NA" por los valores NA manualmente, aquí solo sugiero usar la característica "na.strings" de read.table () para lograr el mismo propósito.
maressyl
La respuesta de Joris es en realidad la forma "preferida" de lograr esta hazaña (si está escribiendo esto en un script). Ver: stackoverflow.com/questions/9860090/…
Jonathan
@Jonathan: Dos ideas distintas aquí, el tema que citas dice "[" debería preferirse en "subconjunto", pero estábamos hablando sobre el argumento "na.strings" en read.table (), mi subconjunto estaba aquí solo para visualizar los efectos.
maressyl
33

complete.casesda TRUEcuando todos los valores en una fila no sonNA

DF[!complete.cases(DF), ]
user3226167
fuente
12
new_data <- data %>% filter_all(any_vars(is.na(.))) 

Esto debería crear un nuevo marco de datos (new_data ) con solo los valores faltantes en él.

Funciona mejor para realizar un seguimiento de los valores que luego podría eliminar porque tenían algunas columnas con observaciones faltantes (NA).

Ronak Pol
fuente
3

Intente cambiar esto:

new_DF<-dplyr::filter(DF,is.na(Var2)) 
drhnis
fuente
¿Podría explicar por qué funciona esto, qué hace, etc.?
csilk
new_DF <-dplyr :: filter (DF, is.na (Var2)) básicamente usa la función de filtro del paquete dplyr y filtra cualquier observación en la columna Var2 que satisfaga la condición is.na, es decir, seleccionan todas las observaciones con NA
drhnis
1
Más bien expresado como DF %>% filter(is.na(Var2))después library(dplyr).
Joe
-1

Imprime todas las filas con datos NA:

tmp <- data.frame(c(1,2,3),c(4,NA,5));
tmp[round(which(is.na(tmp))/ncol(tmp)),]
jstar
fuente
@ZheyuanLi Si no le gusta la respuesta, simplemente elimínela. Editar la respuesta para recomendar marcar NO es la acción apropiada. Deja un comentario si sientes la necesidad.
Manfred Radlwimmer