Capítulo 10 Factores
¿Qué nos puede quedar más allá de las listas? Hay una forma de guardar los datos muy particular en R
, que nos permite diferenciar variables no por su contenido en sí sino por lo que representan: hablemos de factores
Los factores la manera que tiene R
para definir variables categóricas, también llamadas cualitativas, variables que aunque puedan ser números, en realidad representa categorías (categoría 1, 2, 3…). Algunos ejemplos de variables categóricas o cualitativas son las siguientes:
- Estado civil (soltero/casado/viudo)
- Diagnóstico del paciente (sano/leve/grave/fallecido)
- Religión (musulmán/católico/ateo/budista)
- País (España/Francia/Argentina)
- Notas (suspenso/aprobado/notable/sobresaliente)
- Colores (rojo/azul/verde)
- Código postal (28017/34001/18003/33009)
¿Qué diferencias observas entre ellas?
Si las observas, bien algunas de ellas tienen asignadas una jerarquía (orden), a pesar de ser variables cualitativas. Es el caso de notas
y diagnóstico
, y son variables que llamamos variables cualitativas ordinales. En otros casos, no se puede (ni se debería) establecer una jerarquía, como es el caso de estado civil
, religión
, país
, colores
o código postal
, variables cualitativas nominales. Además esta última es especial ya que es una varibale CUALItativa aunque esté formada por números: el código postal, los DNI, las tarjetas sanitarias, son variables que permiten identificar registros, direcciones o inviduos, por lo que su naturaleza no es cuantitativa (no cuantifican ninguna cantidad) sino cualitativa.
Esas variables cualitativas en R
se llaman factores. Internamente los factores se guardan como variable numéricas enteras (enumerando las categorías) pero se nos mostarán con el nombre asignada a dicha categoría. Para convertir una variable a factor basta con ejecutar la función factor()
, que nos convierte cada valor diferente en una categoría (para ver valores diferentes de un vector, usar la función unique()
).
## [1] 1 2 3
datos
## [1] 1 2 3 1 2 3 2 3 3 1
# Convertimos a factor
datos_factor <- factor(datos)
datos_factor
## [1] 1 2 3 1 2 3 2 3 3 1
## Levels: 1 2 3
WARNING: un factor es una CATEGORÍA, no un número
Es importante entender que un factor es una CATEGORÍA, como rojo/blanco/negro, por lo que desde el momento en el que lo convertimos en factor, ya no podemos hacer operaciones aritméticas (no podemos sumar categorías, solo números).
datos + 1
## [1] 2 3 4 2 3 4 3 4 4 2
datos_factor + 1
## [1] NA NA NA NA NA NA NA NA NA NA
Como puedes observar, al tenerlo en factor, además de la variable en sí se nos muestra debajo los levels
, los niveles permitidos de las categorías. Si no le indicamos que nombres queremos, nos convierte los valores a texto y lo toma como nombre de categoría. Con el argumento labels
podemos configurarlo a nuestro gusto. Con la función levels
podemos reasignarle nombres tras su generación.
datos_factor <-
factor(datos, labels = paste("Categoría", sort(unique(datos)))) # damos nombre de categoría 1, 2, 3...
datos_factor
## [1] Categoría 1 Categoría 2 Categoría 3 Categoría 1 Categoría 2 Categoría 3
## [7] Categoría 2 Categoría 3 Categoría 3 Categoría 1
## Levels: Categoría 1 Categoría 2 Categoría 3
## [1] C1 C2 C3 C1 C2 C3 C2 C3 C3 C1
## Levels: C1 C2 C3
Aunque sirve también para variables numéricas, la función table()
nos calcula las frecuencias de cada una de las categorías, las veces que se repiten en nuestro conjunto (es una forma eficiente de guardar categorías ya que solo se guardan los valores únicos y el número de veces que se repiten, así como su lugar).
table(datos_factor)
## datos_factor
## C1 C2 C3
## 3 3 4
Una ventaja de los factores es que le podemos indicar que considere que las categorías son ordinales con el argumento ordered = TRUE
.
notas <- c(7, 2, 10, 5, 7, 8, 10, 8, 2, 2, 5, 5, 5, 10) # notas de clase: tienen un orden
notas_factor <- factor(notas)
notas_factor[1] < notas_factor[2]
## [1] NA
notas_factor_ordenados <- factor(notas, ordered = TRUE)
notas_factor_ordenados
## [1] 7 2 10 5 7 8 10 8 2 2 5 5 5 10
## Levels: 2 < 5 < 7 < 8 < 10
Las variables cualitativas ordinales pueden ser comparadas al tener un orden.
notas_factor_ordenados[1] < notas_factor_ordenados[2] # nos dice que la categoría 7 no es menor que la categoría 2
## [1] FALSE
Y con summary()
además podemos obtener un resumen de nuestras categorías
summary(notas_factor_ordenados)
## 2 5 7 8 10
## 3 4 2 2 3
Para convertir de factor a numérica (y poder operar aritméticamente con ellos), basta usar la función as.numeric()
.
notas_factor_ordenados + 1
## [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA
as.numeric(notas_factor_ordenados) + 1
## [1] 4 2 6 3 4 5 6 5 2 2 3 3 3 6
mean(as.numeric(notas_factor_ordenados))
## [1] 2.857143
También podemos convertir variables continuas (o discretas) a factores indicando los rangos de las categorías que queremos asignar con la función cut()
. Por ejemplo, supongamos que tenemos notas numéricas de clase y queremos asignar una nota categórica. En el argumento breaks
debemos indicarle los cortes que queremos en los datos, teniendo n+1
valores, siendo n
el número de categorías. Con right = FALSE
le vamos a indicar que los intervalos son abiertos por la derecha.
notas <- c(7.4, 1.1, 2.9, 10, 5.2, 7.7, 8.9, 10, 8.1, 2.6, 2.4, 5.5, 5, 5, 10, 6.3, 9.4) # notas de clase
notas_categoricas <- cut(notas, breaks = c(0, 5, 7, 9, 10, 10.1), labels = c("suspenso", "aprobado", "notable", "sobresaliente", "mh"), right = FALSE)
notas_categoricas
## [1] notable suspenso suspenso mh aprobado
## [6] notable notable mh notable suspenso
## [11] suspenso aprobado aprobado aprobado mh
## [16] aprobado sobresaliente
## Levels: suspenso aprobado notable sobresaliente mh
Además, la función cut()
identifica los datos de tipo fecha, pudiendo hacer cortes por unidades temporales.
fechas <- as.Date(c("2021-04-10", "2021-03-10", "2021-01-01", "2020-01-15", "2020-09-10", "2020-09-15", "2020-07-08"))
fechas_cortes <- cut(fechas, breaks = "year")
levels(fechas_cortes) <- c("2020", "2021")
fechas_cortes
## [1] 2021 2021 2021 2020 2020 2020 2020
## Levels: 2020 2021
10.1 Consejos
CONSEJOS
Paquete forcats
En dicho paquete tienes muchas funcionalidades para trabajar con factores. Ver https://forcats.tidyverse.org/.

Imagen/gráfica 10.1: Paquete lubridate.
10.2 📝 Ejercicios
Ejercicio 1: define una variable de 5 elementos con los valores
vector_char <- c("H", "H", "M", "H", "M", "M", "H")
. Convierte la variable a factor, y renombra los niveles como "Hombre"
y "Mujer"
.
- Solución:
# Vector de caracteres
vector_char <- c("H", "H", "M", "H", "M", "M", "H")
vector_char
## [1] "H" "H" "M" "H" "M" "M" "H"
class(vector_char)
## [1] "character"
# Convertimos a factor
vector_factor <- factor(vector_char)
vector_factor
## [1] H H M H M M H
## Levels: H M
class(vector_factor)
## [1] "factor"
## [1] Hombre Hombre Mujer Hombre Mujer Mujer Hombre
## Levels: Hombre Mujer
Ejercicio 2: define un vector con nombres de algunos animales y convierte el vector a factor.
- Solución:
# Ejemplo
animales_char <- c("perro", "gato", "pájaro", "perro", "loro", "gato", "perro", "león")
animales_char
## [1] "perro" "gato" "pájaro" "perro" "loro" "gato" "perro" "león"
class(animales_char)
## [1] "character"
# Convertimos a factor
animales_vector <- factor(animales_char)
animales_vector
## [1] perro gato pájaro perro loro gato perro león
## Levels: gato león loro pájaro perro
class(animales_vector)
## [1] "factor"
Ejercicio 3: define un vector con las notas
notas_char <- c("Suspenso", "Aprobado", "Notable", "Sobresaliente", "Matrícula")
y conviértelo a factor. OJO: ¿es una variable cualitativa nominal u ordinal? Calcula el resumen de la variable.
- Solución:
# Notas (es ordinal)
notas_char <- c("Aprobado", "Suspenso", "Sobresaliente", "Notable",
"Matrícula", "Aprobado", "Aprobado", "Notable",
"Suspenso", "Sobresaliente",
"Matrícula", "Suspenso")
notas_char
## [1] "Aprobado" "Suspenso" "Sobresaliente" "Notable"
## [5] "Matrícula" "Aprobado" "Aprobado" "Notable"
## [9] "Suspenso" "Sobresaliente" "Matrícula" "Suspenso"
# Convertimos a factor ORDENADO
notas_factor <-
factor(notas_char, order = TRUE,
levels = c("Suspenso", "Aprobado", "Notable",
"Sobresaliente", "Matrícula"))
notas_factor
## [1] Aprobado Suspenso Sobresaliente Notable Matrícula
## [6] Aprobado Aprobado Notable Suspenso Sobresaliente
## [11] Matrícula Suspenso
## Levels: Suspenso < Aprobado < Notable < Sobresaliente < Matrícula
# Resumen
summary(notas_factor)
## Suspenso Aprobado Notable Sobresaliente Matrícula
## 3 3 2 2 2
Ejercicio 4: de la variable
notas_char
anterior compara el elemento segundo y el cuarto.
- Solución:
notas_factor[2] < notas_factor[4]
## [1] TRUE
notas_factor[2] > notas_factor[4]
## [1] FALSE