with values name factor data column change r dataframe replace na

values - Reemplace<NA> en una columna de factor



replace na in data frame r (4)

El concepto básico de una variable factorial es que solo puede tomar valores específicos, es decir, los levels . Un valor que no está en los levels no es válido.

Tienes dos posibilidades:

Si tiene una variable que sigue este concepto, asegúrese de definir todos los niveles al crearla, incluso aquellos sin los valores correspondientes.

O haz de la variable una variable de carácter y trabaja con eso.

PD: A menudo, estos problemas resultan de la importación de datos. Por ejemplo, lo que se muestra allí parece que debería ser una variable numérica y no una variable factorial.

Quiero reemplazar los valores <NA> en una columna de factores con un valor válido. Pero no puedo encontrar una manera. Este ejemplo es solo para demostración. Los datos originales provienen de un archivo csv extranjero con el que tengo que tratar.

df <- data.frame(a=sample(0:10, size=10, replace=TRUE), b=sample(20:30, size=10, replace=TRUE)) df[df$a==0,''a''] <- NA df$a <- as.factor(df$a)

Podría verse así

a b 1 1 29 2 2 23 3 3 23 4 3 22 5 4 28 6 <NA> 24 7 2 21 8 4 25 9 <NA> 29 10 3 24

Ahora quiero reemplazar los valores <NA> con un número.

df[is.na(df$a), ''a''] <- 88 In `[<-.factor`(`*tmp*`, iseq, value = c(88, 88)) : invalid factor level, NA generated

Creo que me perdí un concepto R fundamental sobre los factores. Soy yo No puedo entender por qué no funciona. Creo que invalid factor level significa que 88 no es un nivel válido en ese factor, ¿verdad? Entonces, ¿tengo que decirle a la columna de factores que hay otro nivel?


El problema es que NA no es un nivel de ese factor:

> levels(df$a) [1] "2" "4" "5" "9" "10"

No puedes cambiarlo de inmediato, pero lo siguiente hará el truco:

df$a <- as.numeric(as.character(df$a)) df[is.na(df$a),1] <- 88 df$a <- as.factor(df$a) > df$a [1] 9 88 3 9 5 9 88 8 3 9 Levels: 3 5 8 9 88 > levels(df$a) [1] "3" "5" "8" "9" "88"


Otra forma de hacer es:

#check levels levels(df$a) #[1] "3" "4" "7" "9" "10" #add new factor level. i.e 88 in our example df$a = factor(df$a, levels=c(levels(df$a), 88)) #convert all NA''s to 88 df$a[is.na(df$a)] = 88 #check levels again levels(df$a) #[1] "3" "4" "7" "9" "10" "88"


1) addNA Si fac es un factor addNA(fac) es el mismo factor pero con NA agregado como nivel. Ver ?addNA

Para forzar el nivel de NA a ser 88:

facna <- addNA(fac) levels(facna) <- c(levels(fac), 88)

dando:

> facna [1] 1 2 3 3 4 88 2 4 88 3 Levels: 1 2 3 4 88

1a) Esto se puede escribir en una sola línea de la siguiente manera:

`levels<-`(addNA(fac), c(levels(fac), 88))

2) factor También se puede hacer en una línea usando los diversos argumentos de factor como este:

factor(fac, levels = levels(addNA(fac)), labels = c(levels(fac), 88), exclude = NULL)

2a) o equivalentemente:

factor(fac, levels = c(levels(fac), NA), labels = c(levels(fac), 88), exclude = NULL)

3) ifelse Otro enfoque es:

factor(ifelse(is.na(fac), 88, paste(fac)), levels = c(levels(fac), 88))

4) forcats El paquete forcats tiene una función para esto:

library(forcats) fct_explicit_na(fac, "88") ## [1] 1 2 3 3 4 88 2 4 88 3 ## Levels: 1 2 3 4 88

Nota: Usamos lo siguiente para entrada fac

fac <- structure(c(1L, 2L, 3L, 3L, 4L, NA, 2L, 4L, NA, 3L), .Label = c("1", "2", "3", "4"), class = "factor")

Actualización: Han mejorado (1) y agregado (1a). Posteriormente agregado (4).