Es un ejemplo de caso extraido del libro R4DS.
La ordenación de datos es una de las tareas mas importantes despues de concluir la investigación. En las ciencias agrícolas, generalmente la investigación concluye con la evaluación de la cosecha del cultivo. Generalmente nuestros datos pueden estar organizados en un libro de campo; sin embargo, en otras áreas no es así.
En este blog replicaré un ejemplo de ordenación de datos con el paquete Tidyverse
del libro R4DS. El dataset datos::oms
contiene datos de tuberculosis (TB) detallados por año, país, edad, sexo y método de diagnóstico. Los datos provienen del Informe de Tuberculosis de la Organización Mundial de la Salud 2014, disponible en http://www.who.int/tb/country/data/download/en/.
tidyverse
El primer paso es instalar el paquete tidyverse
del CRAN de R. Posterior a esto es cargar el paquete en nuestra consola de R.
library(tidyverse)
#En el paquete datos se encuentra la base de datos para este ejemplo
library(datos)
A continuación observación el estado de los datos de oms
.
head(oms)
# A tibble: 6 x 60
pais iso2 iso3 anio nuevos_fpp_h014 nuevos_fpp_h1524
<chr> <chr> <chr> <int> <int> <int>
1 Afganistán AF AFG 1980 NA NA
2 Afganistán AF AFG 1981 NA NA
3 Afganistán AF AFG 1982 NA NA
4 Afganistán AF AFG 1983 NA NA
5 Afganistán AF AFG 1984 NA NA
6 Afganistán AF AFG 1985 NA NA
# … with 54 more variables: nuevos_fpp_h2534 <int>,
# nuevos_fpp_h3544 <int>, nuevos_fpp_h4554 <int>,
# nuevos_fpp_h5564 <int>, nuevos_fpp_h65 <int>,
# nuevos_fpp_m014 <int>, nuevos_fpp_m1524 <int>,
# nuevos_fpp_m2534 <int>, nuevos_fpp_m3544 <int>,
# nuevos_fpp_m4554 <int>, nuevos_fpp_m5564 <int>,
# nuevos_fpp_m65 <int>, nuevos_fpn_h014 <int>,
# nuevos_fpn_h1524 <int>, nuevos_fpn_h2534 <int>,
# nuevos_fpn_h3544 <int>, nuevos_fpn_h4554 <int>,
# nuevos_fpn_h5564 <int>, nuevos_fpn_h65 <int>,
# nuevos_fpn_m014 <int>, nuevos_fpn_m1524 <int>,
# nuevos_fpn_m2534 <int>, nuevos_fpn_m3544 <int>,
# nuevos_fpn_m4554 <int>, nuevos_fpn_m5564 <int>,
# nuevos_fpn_m65 <int>, nuevos_ep_h014 <int>,
# nuevos_ep_h1524 <int>, nuevos_ep_h2534 <int>,
# nuevos_ep_h3544 <int>, nuevos_ep_h4554 <int>,
# nuevos_ep_h5564 <int>, nuevos_ep_h65 <int>, nuevos_ep_m014 <int>,
# nuevos_ep_m1524 <int>, nuevos_ep_m2534 <int>,
# nuevos_ep_m3544 <int>, nuevos_ep_m4554 <int>,
# nuevos_ep_m5564 <int>, nuevos_ep_m65 <int>,
# nuevosrecaida_h014 <int>, nuevosrecaida_h1524 <int>,
# nuevosrecaida_h2534 <int>, nuevosrecaida_h3544 <int>,
# nuevosrecaida_h4554 <int>, nuevosrecaida_h5564 <int>,
# nuevosrecaida_h65 <int>, nuevosrecaida_m014 <int>,
# nuevosrecaida_m1524 <int>, nuevosrecaida_m2534 <int>,
# nuevosrecaida_m3544 <int>, nuevosrecaida_m4554 <int>,
# nuevosrecaida_m5564 <int>, nuevosrecaida_m65 <int>
En la salida se observa un ejemplo muy típico de una base de datos de la vida real. Contiene columnas redundantes, códigos extraños de variables y muchos valores faltantes. Practicamente, la base de datos oms
está desordenado, por tanto, se necesita ordenarlo de manera sencilla con tidyverse.
Necesitamos agrupar todas las columnas desde nuevos_fpp_h014 hasta recaidas_m65
. No sabemos aún qué representa esto, por lo que le daremos el nombre genérico de "clave"
. Sabemos que las celdas representan la cuenta de casos, por lo que usaremos la variable casos
.
Existen múltiples valores faltantes en la representación actual, por lo que de momento usaremos na.rm
para centrarnos en los valores que están presentes.
oms1 <- oms %>%
pivot_longer(
cols = nuevos_fpp_h014:nuevosrecaida_m65,
names_to = "clave",
values_to = "casos",
values_drop_na = TRUE
)
oms1
# A tibble: 76,046 x 6
pais iso2 iso3 anio clave casos
<chr> <chr> <chr> <int> <chr> <int>
1 Afganistán AF AFG 1997 nuevos_fpp_h014 0
2 Afganistán AF AFG 1997 nuevos_fpp_h1524 10
3 Afganistán AF AFG 1997 nuevos_fpp_h2534 6
4 Afganistán AF AFG 1997 nuevos_fpp_h3544 3
5 Afganistán AF AFG 1997 nuevos_fpp_h4554 5
6 Afganistán AF AFG 1997 nuevos_fpp_h5564 2
7 Afganistán AF AFG 1997 nuevos_fpp_h65 0
8 Afganistán AF AFG 1997 nuevos_fpp_m014 5
9 Afganistán AF AFG 1997 nuevos_fpp_m1524 38
10 Afganistán AF AFG 1997 nuevos_fpp_m2534 36
# … with 76,036 more rows
Para visualizar el conteo de valores en la nueva columna clave
:
oms1 %>%
count(clave)
# A tibble: 56 x 2
clave n
<chr> <int>
1 nuevos_ep_h014 1038
2 nuevos_ep_h1524 1026
3 nuevos_ep_h2534 1020
4 nuevos_ep_h3544 1024
5 nuevos_ep_h4554 1020
6 nuevos_ep_h5564 1015
7 nuevos_ep_h65 1018
8 nuevos_ep_m014 1032
9 nuevos_ep_m1524 1021
10 nuevos_ep_m2534 1021
# … with 46 more rows
Para entender el significado de cada variable, se dispone de un diccionario de datos a mano. Este dice lo siguiente:
Lo que aparece antes del primer _
en las columnas indica si la columna contiene casos nuevos o antiguos de tuberculosis. En este dataset, cada columna contiene nuevos casos.
Lo que aparece luego de indicar si se refiere casos nuevos o antiguos es el tipo de tuberculosis:
recaida
se refiere a casos reincidentesep
se refiere a tuberculosis extra pulmonarfpn
se refiere a casos de tuberculosis pulmonar que no se pueden detectar mediante examen de frotis pulmonar (frotis pulmonar negativo)fpp
se refiere a casos de tuberculosis pulmonar que se pueden detectar mediante examen de frotis pulmonar (frotis pulmonar positivo)La letra que aparece después del último _
se refiere al sexo de los pacientes. El conjunto de datos agrupa en hombres (h
) y mujeres (m
).
Los números finales se refieren al grupo etareo que se ha organizado en siete categorías:
014
= 0 - 14
años de edad1524
= 15 – 24
años de edad2534
= 25 – 34
años de edad3544
= 35 – 44
años de edad4554
= 45 – 54
años de edad5564
= 55 – 64
años de edad65
= 65
o más años de edadNecesitamos hacer un pequeño cambio al formato de los nombres de las columnas: desafortunadamente lo nombres de las columnas son ligeramente inconsistentes debido a que en lugar de nuevos_recaida
tenemos nuevosrecaida
(es difícil darse cuenta de esto en esta parte, pero si no lo arreglas habrá errores en los pasos siguientes). Para esto, la idea básica es bastante simple: reemplazar los caracteres “nuevosrecaida”
por “nuevos_recaida”
. Esto genera nombres de variables consistentes.
oms2 <- oms1 %>%
mutate(clave = stringr::str_replace(clave, "nuevosrecaida", "nuevos_recaida"))
oms2
# A tibble: 76,046 x 6
pais iso2 iso3 anio clave casos
<chr> <chr> <chr> <int> <chr> <int>
1 Afganistán AF AFG 1997 nuevos_fpp_h014 0
2 Afganistán AF AFG 1997 nuevos_fpp_h1524 10
3 Afganistán AF AFG 1997 nuevos_fpp_h2534 6
4 Afganistán AF AFG 1997 nuevos_fpp_h3544 3
5 Afganistán AF AFG 1997 nuevos_fpp_h4554 5
6 Afganistán AF AFG 1997 nuevos_fpp_h5564 2
7 Afganistán AF AFG 1997 nuevos_fpp_h65 0
8 Afganistán AF AFG 1997 nuevos_fpp_m014 5
9 Afganistán AF AFG 1997 nuevos_fpp_m1524 38
10 Afganistán AF AFG 1997 nuevos_fpp_m2534 36
# … with 76,036 more rows
Una vez reemplazado, nos facilita separar los valores en cada código aplicando separate()
dos veces. La primera aplicación dividirá los códigos en cada _
.
oms3 <- oms2 %>%
separate(clave, c("nuevos", "tipo", "sexo_edad"), sep = "_")
oms3
# A tibble: 76,046 x 8
pais iso2 iso3 anio nuevos tipo sexo_edad casos
<chr> <chr> <chr> <int> <chr> <chr> <chr> <int>
1 Afganistán AF AFG 1997 nuevos fpp h014 0
2 Afganistán AF AFG 1997 nuevos fpp h1524 10
3 Afganistán AF AFG 1997 nuevos fpp h2534 6
4 Afganistán AF AFG 1997 nuevos fpp h3544 3
5 Afganistán AF AFG 1997 nuevos fpp h4554 5
6 Afganistán AF AFG 1997 nuevos fpp h5564 2
7 Afganistán AF AFG 1997 nuevos fpp h65 0
8 Afganistán AF AFG 1997 nuevos fpp m014 5
9 Afganistán AF AFG 1997 nuevos fpp m1524 38
10 Afganistán AF AFG 1997 nuevos fpp m2534 36
# … with 76,036 more rows
A continuación podemos eliminar la columna nuevos
, ya que es constante en este dataset. Además eliminaremos iso2
e iso3
ya que son redundantes.
oms3 %>%
count(nuevos)
# A tibble: 1 x 2
nuevos n
<chr> <int>
1 nuevos 76046
oms4 <- oms3 %>%
select(-nuevos, -iso2, -iso3)
Luego separamos sexo_edad
en sexo
y edad
dividiendo luego del primer carácter:
oms5 <- oms4 %>%
separate(sexo_edad, c("sexo", "edad"), sep = 1)
oms5
# A tibble: 76,046 x 6
pais anio tipo sexo edad casos
<chr> <int> <chr> <chr> <chr> <int>
1 Afganistán 1997 fpp h 014 0
2 Afganistán 1997 fpp h 1524 10
3 Afganistán 1997 fpp h 2534 6
4 Afganistán 1997 fpp h 3544 3
5 Afganistán 1997 fpp h 4554 5
6 Afganistán 1997 fpp h 5564 2
7 Afganistán 1997 fpp h 65 0
8 Afganistán 1997 fpp m 014 5
9 Afganistán 1997 fpp m 1524 38
10 Afganistán 1997 fpp m 2534 36
# … with 76,036 more rows
¡Ahora la base de datos oms
está ordenado!
En la anterior sección se hizo el procedimiento de ordenación paso a paso, asignando los resultados intermedios a nuevas variables. Esta no es la forma típica de trabajo. En realidad, los códigos debería ser de manera incremental usando pipes ("%>%)
:
fsdata<- oms %>%
pivot_longer(
cols = nuevos_fpp_h014:nuevosrecaida_m65,
names_to = "clave",
values_to = "valor",
values_drop_na = TRUE) %>%
mutate(clave = stringr::str_replace(clave, "nuevosrecaida", "nuevos_recaida")) %>%
separate(clave, c("nuevos", "tipo", "sexo_edad")) %>%
select(-nuevos, -iso2, -iso3) %>%
separate(sexo_edad, c("sexo", "edad"), sep = 1)
fsdata
# A tibble: 76,046 x 6
pais anio tipo sexo edad valor
<chr> <int> <chr> <chr> <chr> <int>
1 Afganistán 1997 fpp h 014 0
2 Afganistán 1997 fpp h 1524 10
3 Afganistán 1997 fpp h 2534 6
4 Afganistán 1997 fpp h 3544 3
5 Afganistán 1997 fpp h 4554 5
6 Afganistán 1997 fpp h 5564 2
7 Afganistán 1997 fpp h 65 0
8 Afganistán 1997 fpp m 014 5
9 Afganistán 1997 fpp m 1524 38
10 Afganistán 1997 fpp m 2534 36
# … with 76,036 more rows
Es un ejemplo muy bueno para practicar y usar las diferentes funciones de tidyverse
en la ordenación de datos.
For attribution, please cite this work as
Santos (2020, Oct. 31). Franklin Santos: Ordenar datos con el paquete Tidyverse. Retrieved from https://franklinsantos.com/posts/2021-03-14-tidyexam/
BibTeX citation
@misc{santos2020ordenar, author = {Santos, Franklin}, title = {Franklin Santos: Ordenar datos con el paquete Tidyverse}, url = {https://franklinsantos.com/posts/2021-03-14-tidyexam/}, year = {2020} }