Protocolo:
Un factor es una estructura de datos utilizada para campos que sólo toman un número finito y predefinido de valores (datos categóricos). Por ejemplo: un campo de datos como el estado civil puede contener sólo valores de soltero, casado, separado, divorciado o viudo.
En este caso, conocemos los posibles valores de antemano y estos valores predefinidos y distintos se denominan levels
.
Podemos comprobar si una variable es un factor o no utilizando la función class()
.
Del mismo modo, los niveles de un factor se pueden comprobar utilizando la función levels()
.
Podemos crear un factor utilizando la función factor()
. Los niveles de un factor se infieren de los datos si no se proporcionan.
# Vamos a definir el estado civil de alguien:
message("\n# Vamos a definir el estado civil de alguien:")
##
## # Vamos a definir el estado civil de alguien:
Estado_Civil <- factor(c("Soltero", "Casado", "Divorciado", "Casado"))
cat("\nEstado_Civil <- factor(c(\"Soltero\", \"Casado\", \"Divorciado\", \"Casado\"))", "\n \nOUTPUT:\n")
##
## Estado_Civil <- factor(c("Soltero", "Casado", "Divorciado", "Casado"))
##
## OUTPUT:
print(Estado_Civil)
## [1] Soltero Casado Divorciado Casado
## Levels: Casado Divorciado Soltero
# Ahora hagamos un factor con todos los estaddos civiles en colombia:
message("\n# Ahora hagamos un factor con todos los estaddos civiles en colombia:")
##
## # Ahora hagamos un factor con todos los estaddos civiles en colombia:
Estado_Civil <- factor(c("Solter@", "Casad@", "Divorciad@", "Casad@"), levels = c("Solter@", "Casad@", "Divorciad@", "Viud@", "Unión Libre"))
cat("\nEstado_Civil <- factor(c(\"Soltero\", \"Casado\", \"Divorciado\", \"Casado\"),
levels = c(\"Solter@\", \"Casad@\", \"Divorciad@\", \"Viud@\", \"Unión Libre\"))", "\n \nOUTPUT:\n")
##
## Estado_Civil <- factor(c("Soltero", "Casado", "Divorciado", "Casado"),
## levels = c("Solter@", "Casad@", "Divorciad@", "Viud@", "Unión Libre"))
##
## OUTPUT:
print(Estado_Civil)
## [1] Solter@ Casad@ Divorciad@ Casad@
## Levels: Solter@ Casad@ Divorciad@ Viud@ Unión Libre
Podemos ver en el ejemplo anterior que los niveles pueden estar predefinidos aunque no se utilicen.
Los factores están estrechamente relacionados con los vectores. De hecho, los factores se almacenan como vectores enteros. Esto se ve claramente en su estructura.
## Miremos el genero de una persona:
message("\n## Miremos el genero de una persona:")
##
## ## Miremos el genero de una persona:
gener <- factor(c("Hombre", "Mujer", "No Definido", "Trans", "Binario"))
cat("gener <- factor(c(\"Hombre\", \"Mujer\", \"No Definido\", \"Trans\", \"Binario\"))", "\n \nOUTPUT:\n")
## gener <- factor(c("Hombre", "Mujer", "No Definido", "Trans", "Binario"))
##
## OUTPUT:
print(gener)
## [1] Hombre Mujer No Definido Trans Binario
## Levels: Binario Hombre Mujer No Definido Trans
# Ahora vamos observar su estructura:
message("\n# Ahora vamos observar su estructura:")
##
## # Ahora vamos observar su estructura:
cat("str(gener)", "\n \nOUTPUT:\n")
## str(gener)
##
## OUTPUT:
print(str(gener))
## Factor w/ 5 levels "Binario","Hombre",..: 2 3 4 5 1
## NULL
Vemos que los niveles se almacenan en un vector de caracteres y los elementos individuales se almacenan en realidad como índices.
Los factores también se crean cuando leemos columnas no numéricas en un Data Frame.
NOTA: Por defecto, la función
data.frame()
convierte el vector de caracteres en factor. Para suprimir este comportamiento, debemos pasar el argumentostringsAsFactors = FALSE
.
El acceso a los componentes de un factor es muy similar al de los vectores.
# tomamos el factor anterior:
message("# tomamos el factor anterior:")
## # tomamos el factor anterior:
cat("\n> Estado_Civil\n \n")
##
## > Estado_Civil
##
print(Estado_Civil)
## [1] Solter@ Casad@ Divorciad@ Casad@
## Levels: Solter@ Casad@ Divorciad@ Viud@ Unión Libre
# Accediendo al 3er elemento:
cat("\n# Accediendo al 3er elemento:", "\n \n> Estado_Civil[3]", "\n \nOUTPUT:\n")
##
## # Accediendo al 3er elemento:
##
## > Estado_Civil[3]
##
## OUTPUT:
print(Estado_Civil[3])
## [1] Divorciad@
## Levels: Solter@ Casad@ Divorciad@ Viud@ Unión Libre
# Accediendo al 2do y 4to elemento:
cat("\n# Accediendo al 2do y 4to elemento:", "\n \n> Estado_Civil[c(2,4)]", "\n \nOUTPUT:\n")
##
## # Accediendo al 2do y 4to elemento:
##
## > Estado_Civil[c(2,4)]
##
## OUTPUT:
print(Estado_Civil[c(2,4)])
## [1] Casad@ Casad@
## Levels: Solter@ Casad@ Divorciad@ Viud@ Unión Libre
# Accediendo a todos los elementos menos el 1ro:
cat("\n# Accediendo a todos los elementos menos el 1ro:", "\n \n> Estado_Civil[-1]", "\n \nOUTPUT:\n")
##
## # Accediendo a todos los elementos menos el 1ro:
##
## > Estado_Civil[-1]
##
## OUTPUT:
print(Estado_Civil[-1])
## [1] Casad@ Divorciad@ Casad@
## Levels: Solter@ Casad@ Divorciad@ Viud@ Unión Libre
# Usando vectores logicos:
cat("\n# Usando vectores logicos:", "\n \n> Estado_Civil[c(T,F,T,F)]", "\n \nOUTPUT:\n")
##
## # Usando vectores logicos:
##
## > Estado_Civil[c(T,F,T,F)]
##
## OUTPUT:
print(Estado_Civil[c(T,F,T,F)])
## [1] Solter@ Divorciad@
## Levels: Solter@ Casad@ Divorciad@ Viud@ Unión Libre
Los componentes de un factor pueden modificarse mediante simples asignaciones. Sin embargo, no podemos elegir valores fuera de sus niveles predefinidos.
# Tomando el factor de genero:
message("\n# Tomando el factor de genero:")
##
## # Tomando el factor de genero:
print(gener)
## [1] Hombre Mujer No Definido Trans Binario
## Levels: Binario Hombre Mujer No Definido Trans
## Modifiquemos el segundo elemento:
message("\n## Modifiquemos el segundo elemento:")
##
## ## Modifiquemos el segundo elemento:
cat("gener[3] <- \"Mujer\"", "\n \nOUTPUT:\n")
## gener[3] <- "Mujer"
##
## OUTPUT:
gener[3] <- "Mujer"
print(gener)
## [1] Hombre Mujer Mujer Trans Binario
## Levels: Binario Hombre Mujer No Definido Trans
# no se pueden asignar valores fuera de los niveles:
message("\n# no se pueden asignar valores fuera de los niveles:\n")
##
## # no se pueden asignar valores fuera de los niveles:
gener[5] <- "Otro"
## Warning in `[<-.factor`(`*tmp*`, 5, value = "Otro"): invalid factor level, NA
## generated
cat("gener[5] <- \"Otro\"", "\n \nOUTPUT:\n")
## gener[5] <- "Otro"
##
## OUTPUT:
print(gener[5])
## [1] <NA>
## Levels: Binario Hombre Mujer No Definido Trans
Una solución a esto es añadir el valor al nivel primero.
# Una solución a esto es añadir el valor al nivel primero:
message("\n# Una solución a esto es añadir el valor al nivel primero:\n")
##
## # Una solución a esto es añadir el valor al nivel primero:
## Añadir un nuevo level:
message("\n## Añadir un nuevo level:")
##
## ## Añadir un nuevo level:
levels(gener) <- c(levels(gener), "Otro")
cat("levels(gener) <- c(levels(gener), \"Otro\")", "\n \nOUTPUT:\n")
## levels(gener) <- c(levels(gener), "Otro")
##
## OUTPUT:
print(levels(gener))
## [1] "Binario" "Hombre" "Mujer" "No Definido" "Trans"
## [6] "Otro"
## AHora cambiamos otro por "No Definido":
message("\n## AHora cambiamos otro por \"No Definido\":\n")
##
## ## AHora cambiamos otro por "No Definido":
gener[5] <- "Otro"
cat("gener[5] <- \"Otro\"", "\n \nOUTPUT:\n")
## gener[5] <- "Otro"
##
## OUTPUT:
print(gener)
## [1] Hombre Mujer Mujer Trans Otro
## Levels: Binario Hombre Mujer No Definido Trans Otro