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