Continuando con el tema de limpieza de datos, haremos una lista de funciones de la familia de librerías denominada: tidyverse. Vale la pena resaltar que esta librería es un compendido de muchas librerías de las cuales algunas mencionamos la clase pasada (tidyr,dplyr,tibble,stringr,ggplot2,purr,magrittr, etc)
Función | Utilidad |
---|---|
%>% |
“canalizar” (pasar) datos de una función a la siguiente |
filter() |
mantener ciertas filas |
selecct() |
mantener, eliminar, seleccionar o renombrar columnas |
mutate() |
crear, transformar y redefinir columnas |
arrange() |
ordenar las filas |
recode() |
recodificar los valores de una columna |
rename() |
cambiar el nombre de las columnas |
clean_names() |
estandarizar la sintaxis de los nombres de las columnas |
across() |
transformar varias columnas a la vez |
as.character() , as.numeric() ,
as.Date() , … |
convertir el tipo de una columna |
distinct() |
eliminar copias duplicadas de datos |
rowwise() |
operaciones por/en cada fila |
add_row() |
añadir filas manualmente |
case_when() |
recodificar los valores de una columna con criterios lógicos más complejos |
replace_na() ,na_if() ,
coalesce() |
funciones especiales de recodificación |
age_categories() y cut() |
crear grupos categóricos a partir de una columna |
match_df() |
recodificación/limpieza de valores mediante un diccionario de datos |
which() |
aplicar los criterios lógicos; devuelve los índices |
El siguiente código muestra la carga de las librerías necesarias para
el análisis. En este clase destacamos p_load()
de pacman,
que instala la librería si es necesario y lo carga para su uso. También
puedes cargar los paquetes instalados con library() de
R.
pacman::p_load(
rio, # importación/exportación de múltiples tipos de datos
here, # ruta relativa de los archivos
janitor, # limpieza de datos y tablas
lubridate, # trabajar con fechas
epikit, # función age_categories()
tidyverse, # gestión y visualización de datos
naniar # evaluar y visualizar datos faltantes
)
Trabajaremos con una base de datos muy importante sobre la simulación
de un brote del virus del Ébola. Importamos el archivo Excel de la lista
de casos “en bruto” utilizando la función import()
de la librería rio. Esta librería
maneja con flexibilidad muchos tipos de archivos (.xlsx, .csv, .tsv,
.rds.). Consulta el documento sobre importar
y exportar para obtener más información y consejos sobre situaciones
inusuales (por ejemplo, omitir filas, establecer valores que faltan,
importar hojas de Google, etc).
linelist_raw <- import("linelist_raw.xlsx")
DT::datatable(head(linelist_raw[,1:5],50))
Puedes utilizar la función skim()
del paquete skimr para obtener
una visión general de todo la base de datos. Las columnas se resumen por
clase o tipo, como por ejemplo: carácter, numérico. Nota: “POSIXct” es
un tipo de fecha.
skimr::skim(linelist_raw)
Name | linelist_raw |
Number of rows | 6611 |
Number of columns | 28 |
_______________________ | |
Column type frequency: | |
character | 17 |
numeric | 8 |
POSIXct | 3 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
case_id | 137 | 0.98 | 6 | 6 | 0 | 5888 | 0 |
date onset | 293 | 0.96 | 10 | 10 | 0 | 580 | 0 |
outcome | 1500 | 0.77 | 5 | 7 | 0 | 2 | 0 |
gender | 324 | 0.95 | 1 | 1 | 0 | 2 | 0 |
hospital | 1512 | 0.77 | 5 | 36 | 0 | 13 | 0 |
infector | 2323 | 0.65 | 6 | 6 | 0 | 2697 | 0 |
source | 2323 | 0.65 | 5 | 7 | 0 | 2 | 0 |
age | 107 | 0.98 | 1 | 2 | 0 | 75 | 0 |
age_unit | 7 | 1.00 | 5 | 6 | 0 | 2 | 0 |
fever | 258 | 0.96 | 2 | 3 | 0 | 2 | 0 |
chills | 258 | 0.96 | 2 | 3 | 0 | 2 | 0 |
cough | 258 | 0.96 | 2 | 3 | 0 | 2 | 0 |
aches | 258 | 0.96 | 2 | 3 | 0 | 2 | 0 |
vomit | 258 | 0.96 | 2 | 3 | 0 | 2 | 0 |
time_admission | 844 | 0.87 | 5 | 5 | 0 | 1091 | 0 |
merged_header | 0 | 1.00 | 1 | 1 | 0 | 1 | 0 |
…28 | 0 | 1.00 | 1 | 1 | 0 | 1 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
generation | 7 | 1.00 | 16.60 | 5.71 | 0.00 | 13.00 | 16.00 | 20.00 | 37.00 | ▁▆▇▂▁ |
lon | 7 | 1.00 | -13.23 | 0.02 | -13.27 | -13.25 | -13.23 | -13.22 | -13.21 | ▅▃▃▅▇ |
lat | 7 | 1.00 | 8.47 | 0.01 | 8.45 | 8.46 | 8.47 | 8.48 | 8.49 | ▅▇▇▇▆ |
row_num | 0 | 1.00 | 3240.91 | 1857.83 | 1.00 | 1647.50 | 3241.00 | 4836.50 | 6481.00 | ▇▇▇▇▇ |
wt_kg | 7 | 1.00 | 52.69 | 18.59 | -11.00 | 41.00 | 54.00 | 66.00 | 111.00 | ▁▃▇▅▁ |
ht_cm | 7 | 1.00 | 125.25 | 49.57 | 4.00 | 91.00 | 130.00 | 159.00 | 295.00 | ▂▅▇▂▁ |
ct_blood | 7 | 1.00 | 21.26 | 1.67 | 16.00 | 20.00 | 22.00 | 22.00 | 26.00 | ▁▃▇▃▁ |
temp | 158 | 0.98 | 38.60 | 0.95 | 35.20 | 38.30 | 38.80 | 39.20 | 40.80 | ▁▂▂▇▁ |
Variable type: POSIXct
skim_variable | n_missing | complete_rate | min | max | median | n_unique |
---|---|---|---|---|---|---|
infection date | 2322 | 0.65 | 2012-04-09 | 2015-04-27 | 2014-10-04 | 538 |
hosp date | 7 | 1.00 | 2012-04-20 | 2015-04-30 | 2014-10-15 | 570 |
date_of_outcome | 1068 | 0.84 | 2012-05-14 | 2015-06-04 | 2014-10-26 | 575 |
En R, los nombres de las columnas son la “cabecera” o el valor “superior” de una columna. Se utilizan para referirse a las columnas en el código, y sirven como etiqueta por defecto en las figuras.
Otros programas estadísticos, como SAS y STATA, utilizan “etiquetas” que coexisten como versiones impresas más largas de los nombres de columna más cortos. Aunque R ofrece la posibilidad de añadir etiquetas de columna a los datos, no es una práctica que sea muy utilizada. Para hacer que los nombres de las columnas sean “fáciles de imprimir” para las figuras, normalmente se ajusta su visualización dentro de los comandos de gráficas que crean las salidas (por ejemplo, los títulos de los ejes o de las leyendas de una gráfica, o las cabeceras de las columnas en una tabla impresa).
Como los nombres de las columnas de R se utilizan con mucha frecuencia, deben tener una sintaxis “limpia”. Se sugieren lo siguiente:
names(linelist_raw)
## [1] "case_id" "generation" "infection date" "date onset"
## [5] "hosp date" "date_of_outcome" "outcome" "gender"
## [9] "hospital" "lon" "lat" "infector"
## [13] "source" "age" "age_unit" "row_num"
## [17] "wt_kg" "ht_cm" "ct_blood" "fever"
## [21] "chills" "cough" "aches" "vomit"
## [25] "temp" "time_admission" "merged_header" "...28"
Podemos ver que los nombres de las columnas de nuestra base de datos inicialmente:
La función clean_names()
del paquete janitor
estandariza los nombres de las columnas y los hace únicos haciendo lo
siguiente:
case = argumento
(“snake” es el valor por defecto, las alternativas incluyen “sentence”,
“title”, “small_camel”,…).replace = c(onset = "date_of_onset")
).Para más información de esta librería, puedes consultar:Janitor
# Renombrar columnas automaticamente
linelist <- linelist_raw %>%
janitor::clean_names()
names(linelist)
## [1] "case_id" "generation" "infection_date" "date_onset"
## [5] "hosp_date" "date_of_outcome" "outcome" "gender"
## [9] "hospital" "lon" "lat" "infector"
## [13] "source" "age" "age_unit" "row_num"
## [17] "wt_kg" "ht_cm" "ct_blood" "fever"
## [21] "chills" "cough" "aches" "vomit"
## [25] "temp" "time_admission" "merged_header" "x28"
A menudo es necesario renombrar las columnas manualmente, incluso
después del paso anterior. Renombrar variables lo podemos hacer con la
función rename()
,
como parte de una cadena de pipes. Esta función utiliza el estilo
nombre_nuevo = nombre_anterior
(el nombre nuevo de la
columna se escribe antes que el antiguo).
# Renombrar columnas manualmente
linelist <- linelist_raw %>%
janitor::clean_names() %>%
# nombre nuevo # nombre anterior
rename(date_infection = infection_date,
date_hosp = hosp_date,
date_outcome = date_of_outcome)
names(linelist)
## [1] "case_id" "generation" "date_infection" "date_onset"
## [5] "date_hosp" "date_outcome" "outcome" "gender"
## [9] "hospital" "lon" "lat" "infector"
## [13] "source" "age" "age_unit" "row_num"
## [17] "wt_kg" "ht_cm" "ct_blood" "fever"
## [21] "chills" "cough" "aches" "vomit"
## [25] "temp" "time_admission" "merged_header" "x28"
También puedes renombrar por la posición de la columna, en lugar del nombre de la columna, por ejemplo:
linelist <- linelist %>%
rename(id = 1,
Group = 2)
names(linelist)
## [1] "id" "Group" "date_infection" "date_onset"
## [5] "date_hosp" "date_outcome" "outcome" "gender"
## [9] "hospital" "lon" "lat" "infector"
## [13] "source" "age" "age_unit" "row_num"
## [17] "wt_kg" "ht_cm" "ct_blood" "fever"
## [21] "chills" "cough" "aches" "vomit"
## [25] "temp" "time_admission" "merged_header" "x28"
Como método abreviado, también puedes cambiar el nombre de las
columnas dentro de las funciones select()
y summarise()
.
Estas funciones también utilizan el formato
nombre_nuevo = nombre_anterior
.
# Selecciona y renombra estas columnas:
Select_linelist_raw <- linelist_raw %>%
select(# nombre nuevo # nombre anterior
date_infection = `infection date`,
date_hosp = `hosp date`)
names(Select_linelist_raw)
## [1] "date_infection" "date_hosp"
Como ya vimos en la clase anterior, la función select()
,
nos ayuda a seleccionar sólo las columnas que necesitemos conservar,
pero también puede servir para especificar el orden que deseamos.
Por ejemplo, si deseas reordenar las columnas,
everything()
es un argumento útil para
indicar “todas las demás columnas no mencionadas”
# mueve date_onset y date_hospitalisation al principio
linelist %>%
select(date_onset, date_hosp, everything()) %>%
names()
## [1] "date_onset" "date_hosp" "id" "Group"
## [5] "date_infection" "date_outcome" "outcome" "gender"
## [9] "hospital" "lon" "lat" "infector"
## [13] "source" "age" "age_unit" "row_num"
## [17] "wt_kg" "ht_cm" "ct_blood" "fever"
## [21] "chills" "cough" "aches" "vomit"
## [25] "temp" "time_admission" "merged_header" "x28"
Hay un gran número de argumentos de ayuda que también funcionan
dentro de las funciones como: select()
,
across()
y summarise()
:
last_col()
: la última columna.where()
: aplica una función lógica a
todas las columnas y selecciona las que cumplen.contains()
: columnas que contienen una
cadena de caracteres.
select(contains("time"))
.starts_with()
:coincide con un prefijo
especificado.
select(starts_with("date_"))
.ends_with()
: coincide con un sufijo
especificado.
select(ends_with("_post))
.matches()
: para aplicar una expresión
regular.
select(matches("[pt]al"))
.num_range()
: un rango numérico como
x01, x02, x03.any_of()
: coincide con la columna SI
existe pero no devuelve ningún error si no se encuentra.
select(any_of(date_onset, date_death, cardiac_arrest))
.Además, utiliza operadores ya trabajados como
c()
para listar varias columnas,
:
para columnas consecutivas,
!
para opuestos,
&
para “y” y
|
para “o”.
Algunos ejemplos de la utilidad de estos argumentos:
# selecciona las columnas que son de clase Numeric
linelist %>%
select(where(is.numeric)) %>%
names()
## [1] "Group" "lon" "lat" "row_num" "wt_kg" "ht_cm" "ct_blood"
## [8] "temp"
# selecciona las columnas que contienen ciertos caracteres
linelist %>%
select(contains("date")) %>%
names()
## [1] "date_infection" "date_onset" "date_hosp" "date_outcome"
# selecciona las columnas id y age-related
linelist %>%
select(id, contains("age")) %>%
names()
## [1] "id" "age" "age_unit"
# selecciona por multiples coincidencias de caracteres
linelist %>%
select(matches("onset|hosp|fev")) %>%
names()
## [1] "date_onset" "date_hosp" "hospital" "fever"
Nota importante: en este último ejemplo, si has
escrito un nombre de columna y no existen datos para ella, puede
devolver un error y detener tu código. Considera el uso del argumento
any_of()
para citar columnas que pueden o
no existir, especialmente útil en selecciones negativas (eliminar).
linelist %>%
select(any_of(c("date_onset", "village_origin", "village_detection", "village_residence", "village_travel"))) %>%
names()
## [1] "date_onset"
Es una tarea muy importante en la limpieza de datos y muy complicada de realizar de forma manual.
Para revisar las filas que tienen duplicados, puedes utilizar la
función get_dupes()
del paquete janitor. Las filas
devueltas por la función están 100% duplicadas considerando los valores
de todas las columnas.
linelist %>%
janitor::get_dupes()
## id Group date_infection date_onset date_hosp date_outcome outcome gender
## 1 <NA> 16 2014-10-22 2014-11-03 2014-11-05 2014-11-16 <NA> f
## 2 <NA> 16 2014-10-22 2014-11-03 2014-11-05 2014-11-16 <NA> f
## 3 <NA> 20 2014-12-25 2015-01-04 2015-01-06 2015-01-16 Recover m
## 4 <NA> 20 2014-12-25 2015-01-04 2015-01-06 2015-01-16 Recover m
## hospital lon lat infector source age age_unit row_num
## 1 Military Hospital -13.21947 8.483222 f17d9f other 34 years 2987
## 2 Military Hospital -13.21947 8.483222 f17d9f other 34 years 2987
## 3 Military Hospital -13.23220 8.472805 994b0d other 44 years 3811
## 4 Military Hospital -13.23220 8.472805 994b0d other 44 years 3811
## wt_kg ht_cm ct_blood fever chills cough aches vomit temp time_admission
## 1 70 178 21 yes no yes no no 38.6 14:42
## 2 70 178 21 yes no yes no no 38.6 14:42
## 3 78 190 21 yes no yes no no 38.5 17:08
## 4 78 190 21 yes no yes no no 38.5 17:08
## merged_header x28 dupe_count
## 1 a b 2
## 2 a b 2
## 3 a b 2
## 4 a b 2
Observemos que crea una columna
dupe_count
que indica el número de eces
que encontró la observación repetida. También se pueden encontrar
duplicados de algunas columnas especificas. Si no quieres ver toda la
lista, pues pueden ser extensa, simplemente puedes contar los duplicados
que cumplan la condición dada.
linelist %>%
janitor::get_dupes(-gender)
## id Group date_infection date_onset date_hosp date_outcome outcome
## 1 <NA> 16 2014-10-22 2014-11-03 2014-11-05 2014-11-16 <NA>
## 2 <NA> 16 2014-10-22 2014-11-03 2014-11-05 2014-11-16 <NA>
## 3 <NA> 20 2014-12-25 2015-01-04 2015-01-06 2015-01-16 Recover
## 4 <NA> 20 2014-12-25 2015-01-04 2015-01-06 2015-01-16 Recover
## hospital lon lat infector source age age_unit row_num
## 1 Military Hospital -13.21947 8.483222 f17d9f other 34 years 2987
## 2 Military Hospital -13.21947 8.483222 f17d9f other 34 years 2987
## 3 Military Hospital -13.23220 8.472805 994b0d other 44 years 3811
## 4 Military Hospital -13.23220 8.472805 994b0d other 44 years 3811
## wt_kg ht_cm ct_blood fever chills cough aches vomit temp time_admission
## 1 70 178 21 yes no yes no no 38.6 14:42
## 2 70 178 21 yes no yes no no 38.6 14:42
## 3 78 190 21 yes no yes no no 38.5 17:08
## 4 78 190 21 yes no yes no no 38.5 17:08
## merged_header x28 dupe_count gender
## 1 a b 2 f
## 2 a b 2 f
## 3 a b 2 m
## 4 a b 2 m
Para eliminar estas filas encontradas repetidas, utiliza la función
distinct()
.
Las filas duplicadas se eliminan de forma que sólo se conserva la
primera de dichas filas.
# dimensión con duplicados
dim(linelist)
## [1] 6611 28
linelist <- linelist %>%
distinct()
# dimensión sin duplicados
dim(linelist)
## [1] 6609 28
# Datos faltantes por columna
gg_miss_var(linelist)
# Gráfico de valores faltantes en todo el dataframe
vis_miss(linelist)
Existen varias funciones útiles para el manejo de datos faltantes. Como lo son:
pct_miss()
:
puedes ver tres variantes de esta función, las cuales encuentran el
porcentaje de valores faltantes según la especificación.# Porcentaje de TODOS los valores faltantes
pct_miss(linelist)
## [1] 7.7027
# Porcentaje de filas en las que falta algún valor
pct_miss_case(linelist) # usa n_complete() para los recuentos
## [1] 76.15373
## [1] 69.12364
# Porcentaje de filas que están completas (no faltan valores)
pct_complete_case(linelist) # usa n_complete() para los recuentos
## [1] 23.84627
is.na()
y !is.na()
:
utiliza is.na()
para identificar los
valores que faltan, o utiliza su opuesto (con ! delante) para
identificar los valores que no faltan. Ambos devuelven un valor lógico
(TRUE o FALSE). Recuerda que puedes sumar
(sum()
) el vector resultante para contar
el número de TRUE.sum(is.na(linelist$date_outcome))
## [1] 1068
na.omit()
:
esta función eliminará las filas con valores faltantes.my_vector <- c(1, 56, NA, 5, NA, 22)
na.omit(my_vector)
## [1] 1 56 5 22
## attr(,"na.action")
## [1] 3 5
## attr(,"class")
## [1] "omit"
na.rm = TRUE
:
cuando se ejecuta alguna función matemática como
max()
,
min()
, sum()
o mean()
, si hay algún valor
NA presente el valor devuelto será NA. Este
comportamiento por defecto es intencionado, para avisar que falta algún
dato.Puedes evitarlo eliminando los valores faltantes del cálculo. Para
ello, incluye el argumento na.rm = TRUE
(significa “eliminar NA”).
mean(my_vector)
## [1] NA
mean(my_vector, na.rm = TRUE)
## [1] 21
drop_na()
:
si se ejecuta con los paréntesis vacíos, elimina las filas con valores
faltantes. Si se especifican los nombres de las columnas en los
paréntesis, se eliminarán las filas con valores faltantes en esas
columnas.linelist3 <- linelist %>%
drop_na(source, infector, date_infection)
dim(linelist)
## [1] 6609 28
dim(linelist3)
## [1] 4286 28
Recomendamos que podemos utilizar la función mutate()
para añadir una nueva columna, o para modificar una existente.
Se pueden crear nuevas columnas realizando operaciones con las demás columnas.
linelist <- linelist %>%
mutate(bmi = wt_kg / (ht_cm/100)^2)
names(linelist)
## [1] "id" "Group" "date_infection" "date_onset"
## [5] "date_hosp" "date_outcome" "outcome" "gender"
## [9] "hospital" "lon" "lat" "infector"
## [13] "source" "age" "age_unit" "row_num"
## [17] "wt_kg" "ht_cm" "ct_blood" "fever"
## [21] "chills" "cough" "aches" "vomit"
## [25] "temp" "time_admission" "merged_header" "x28"
## [29] "bmi"
También simplemente colocando un valor fijo.
linelist <- linelist %>%
mutate(new_col = 10)
names(linelist)
## [1] "id" "Group" "date_infection" "date_onset"
## [5] "date_hosp" "date_outcome" "outcome" "gender"
## [9] "hospital" "lon" "lat" "infector"
## [13] "source" "age" "age_unit" "row_num"
## [17] "wt_kg" "ht_cm" "ct_blood" "fever"
## [21] "chills" "cough" "aches" "vomit"
## [25] "temp" "time_admission" "merged_header" "x28"
## [29] "bmi" "new_col"
Las columnas que contienen valores que son fechas, números o valores lógicos (TRUE/FALSE) sólo se comportarán como se espera si están correctamente clasificadas. Hay una diferencia entre “2” de tipo carácter y 2 de tipo numérico.
Vimos al inicio con ayuda de la función skim()
,
como R guardo el tipo de cada variable. Por ejemplo: el
tipo de la columna age es un carácter, pero esto no es
correcto. Para realizar análisis cuantitativos, ¡necesitamos que estos
números sean reconocidos como numéricos!.
# Tipo original
class(linelist$age)
## [1] "character"
linelist <- linelist %>%
mutate(age = as.numeric(age))
# Variable trasformada
class(linelist$age)
## [1] "numeric"
De forma similar, puedes utilizar
as.character()
y
as.logical()
,
as.Date
,
factor()
.
Otro problema que podemos visualizar en las variables, es que por ejemplo: date_onset aparece como carácter, pero para cualquier análisis esta variable debe ser reconocida como fecha.
# Tipo original
class(linelist$date_onset)
## [1] "character"
linelist <- linelist %>%
mutate(date_onset = as.Date(date_onset))
# Tipo original
class(linelist$date_onset)
## [1] "Date"
También podemos aprovechar la función group_by()
para hacer transformaciones por medio de grupos.
# Edad normalizada para hacer la media de TODAS las filas
linelist1 <- linelist %>% select(age) %>%
mutate(age_norm = (age - mean(age, na.rm=T))/ sd(age, na.rm=T))
head(linelist1)
## age age_norm
## 1 2 -1.117313654
## 2 3 -1.038052358
## 3 56 3.162796350
## 4 18 0.150867088
## 5 3 -1.038052358
## 6 16 -0.007655505
# Edad normalizada para hacer la media por grupo de hospital
linelist2 <- linelist %>% select(age,hospital) %>%
group_by(hospital) %>%
mutate(age_norm = (age - mean(age, na.rm=T))/ sd(age, na.rm=T))
head(linelist2)
## # A tibble: 6 × 3
## # Groups: hospital [5]
## age hospital age_norm
## <dbl> <chr> <dbl>
## 1 2 Other -1.13
## 2 3 <NA> -1.01
## 3 56 St. Mark's Maternity Hospital (SMMH) 3.38
## 4 18 Port Hospital 0.132
## 5 3 Military Hospital -1.05
## 6 16 Port Hospital -0.0262
A menudo, para escribir un código conciso, se desea aplicar la misma
transformación a varias columnas a la vez. Se puede aplicar una
transformación a varias columnas a la vez utilizando el argumento
across()
.
linelist <- linelist %>%
mutate(across(.cols = c(temp, ht_cm, wt_kg), .fns = as.character))
También se puede crear una nueva variable por medio de múltiples existentes.
linelist <- linelist %>%
# crear la columna age_years (A partir de age y age_unit)
mutate(age_years = case_when(
age_unit == "years" ~ age,
age_unit == "months" ~ age/12,
is.na(age_unit) ~ age))
En algunas ocasiones es importante cambiar una variable numérica a categórica. Algunos ejemplos comunes son las categorías de edad, los grupos de valores de laboratorio, etc.
class(linelist$age_years)
## [1] "numeric"
# Examine la distribución
hist(linelist$age_years,xlab=" ",main=" ",col="lightblue")
summary(linelist$age_years, na.rm=T)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.00 6.00 13.00 16.04 23.00 84.00 107
Con ayuda de la función age_categories()
puedes categorizar y etiquetar fácilmente las columnas numéricas.
linelist <- linelist %>%
mutate(age_cat = age_categories( # crear una columna nueva
age_years, # columna numérica para hacer grupos
breakers = c(0, 5, 10, 15, 20, 30, 40, 50, 60, 70)))
table(linelist$age_cat, useNA = "always")
##
## 0-4 5-9 10-14 15-19 20-29 30-39 40-49 50-59 60-69 70+ <NA>
## 1227 1223 1048 828 1216 597 251 78 27 7 107
Los valores de ruptura que especificas son por defecto los límites inferiores. Es decir, están incluidos en el grupo “superior”, los grupos están “abiertos” en la parte inferior/izquierda. Pero se puede hacer lo contrario si se desea.
# Crear una nueva variable, cortando la variable numérica age
# Se excluye el corte inferior pero se incluye el superior en cada categoría
linelist <- linelist %>%
mutate(
age_cat = cut(
age_years,
breaks = c(0, 5, 10, 15, 20,
30, 50, 70, 100),
include.lowest = TRUE # # incluye 0 en el grupo más bajo
))
# tabular el número de observaciones por grupo
table(linelist$age_cat, useNA = "always")
##
## [0,5] (5,10] (10,15] (15,20] (20,30] (30,50] (50,70] (70,100]
## 1469 1195 1041 770 1149 778 94 6
## <NA>
## 107
También se pueden hacer las divisiones por medio de los cuartiles.
quantile(linelist$age_years,na.rm = TRUE)
## 0% 25% 50% 75% 100%
## 0 6 13 23 84
O especificando los percentiles.
quantile(linelist$age_years,
probs = c(0, .25, .50, .75, .90, .95),
na.rm = TRUE)
## 0% 25% 50% 75% 90% 95%
## 0 6 13 23 33 41
\[ \]