/ / ¿Por qué na.omit agrega una fila al marco de datos vacío? - r, marco de datos

¿Por qué na.omit agrega una fila al dataframe vacío? - r, marco de datos

Tengo un código que estaba haciendo algo como

d <- load a data.frame, possible an empty one...
d <- na.omit(d)
if (NROW(d)>0) {
do something...
}

Esto parece ser incorrecto debido al hecho de que la aplicación na.omit a un marco de datos vacío le agrega una fila:

data.frame()
data frame with 0 columns and 0 rows

na.omit(data.frame())
data frame with 0 columns and 1 rows

¿Por qué na.omit me está haciendo esto?

Respuestas

4 para la respuesta № 1

Esto es porque na.omit tiene un vector lógico omit (en su código) que se pone a FALSE para esas filas a mantener y TRUE para esas filas a retirar.

Sin embargo, omit inicialmente se establece en FALSE antes de verificar los datos de entrada en el marco de qué filas eliminar y actualizar el valor de omit. Dado que su entrada es un data.frame vacío, no hay valores que se actualicen y omit conserva el conjunto anterior FALSO. Y entonces, na.omit llamadas:

object[!omit, , drop=FALSE]

que en tu caso es:

data.frame()[TRUE, , drop=FALSE]

lo que da:

# data frame with 0 columns and 1 rows

Aquí está el código para na.omit.data.frame (que se puede obtener haciendo getS3method("na.omit", "data.frame")). La parte que no se ejecuta para su data.frame vacío está comentada.

n <- length(object)
omit <- FALSE
vars <- seq_len(n) # equals integer(0) in your case
for (j in vars) { # the loop is not run at all
#     x <- object[[j]]
#     if (!is.atomic(x))
#         next
#     x <- is.na(x)
#     d <- dim(x)
#     if (is.null(d) || length(d) != 2L)
#         omit <- omit | x
#     else for (ii in 1L:d[2L]) omit <- omit | x[, ii]
# }
xx <- object[!omit, , drop = FALSE]
# if (any(omit > 0L)) { # this is also not run
#     temp <- setNames(seq(omit)[omit], attr(object, "row.names")[omit])
#     attr(temp, "class") <- "omit"
#     attr(xx, "na.action") <- temp
# }
xx

Solución:

podrías usar complete.cases en lugar.

DF <- data.frame()
DF[complete.cases(DF), ]
# data frame with 0 columns and 0 rows

DF <- data.frame(x=1:2, y=c(2,NA))
DF[complete.cases(DF), ]
#   x y
# 1 1 2

1 para la respuesta № 2

El problema no es con (necesariamente) con na.omit, sino más bien con indexar un data.frame que no tiene filas. p.ej:

> DF <- data.frame()
> DF[TRUE, ]
data frame with 0 columns and 1 rows
> DF[1, ]
data frame with 0 columns and 1 rows
> DF
data frame with 0 columns and 0 rows

No puede realmente indexar un data.frame y recuperar un data.frame de 0 filas.

Una solución es usar lógica condicional:

if (!nrow(DF))
do nothing
else
na.omit(DF) ...

Una mejor solución es usar la sugerencia de @Arun