Introducción

Las tasas crudas y ajustadas de mortalidad son dos de los indicadores más utilizados en epidemiología. Sirven para hacer comparaciones entre diferentes poblaciones y períodos de tiempo.

El procedimiento para el cálculo de tasas de mortalidad es sencillo, sin embargo, al tener denominador y numerador fuentes de información distintas, requiere habitualmente el cumplimiento de ciertos pasos: obtención de la información, adaptación de los formatos, homologación de categorías, etc. Estas tareas suelen ser tediosas y aumentan la probabilidad de cometer errores. Por otro lado, cuando los cálculos deben hacerse para múltiples áreas geográficas o períodos de tiempo, suelen ser poco eficientes.

 

Objetivo

El objetivo de este documento es presentar una forma programática en R (R Core Team 2019) para el cálculo de tasas de mortalidad por año, jurisdicción y sexo para Argentina en el período 2010-2021.

 

Desarrollo

Para el desarrollo de esta actividad se utilizarán las librerías dplyr (Wickham et al. 2023),epitools (Aragon 2020),readr (Wickham, Hester, and Bryan 2022) y DT (Xie, Cheng, and Tan 2023).

1- Descarga de los datos

En el portal de Datos Abiertos se encuentra disponible un dataset de defunciones ocurridas y registradas en Argentina para el período 2005-2021. En este archivo las muertes están clasificadas por una serie de variables y en la columna “cantidad” presenta una cuenta de defunciones para la combinación de categorías de cada fila.

Descargamos el archivo y creamos el data frame “defunciones”.

library(dplyr)
options(timeout=1000000) # incrementamos el timeout debido a que la descarga es lenta

url = "http://datos.salud.gob.ar/dataset/27c588e8-43d0-411a-a40c-7ecc563c2c9f/resource/fab9e990-865c-43c4-a643-3dbc3b70a934/download/defunciones-ocurridas-y-registradas-en-la-republica-argentina-anos-2005-2021.csv"

download.file(url, destfile = "defunciones.csv")

defunciones = read.csv("defunciones.csv", encoding = "latin1")
unlink("defunciones.csv")

2- Procesamiento de la información de mortalidad

El archivo de defunciones tiene 778.353 registros. Debido a que vamos a utilizar sólo el período 2010-2021, eliminamos los años anteriores.

defunciones = defunciones[defunciones$anio >= 2010,] 

# observamos la estructura del data frame
str(defunciones)
## 'data.frame':    558016 obs. of  11 variables:
##  $ anio                         : int  2014 2016 2012 2021 2016 2017 2013 2014 2014 2017 ...
##  $ jurisdiccion_de_residencia_id: int  34 94 90 62 14 86 2 78 58 54 ...
##  $ jurisdicion_residencia_nombre: chr  "Formosa" "Tierra del Fuego, Antártida e Islas del Atlántico Sur" "Tucumán" "Río Negro" ...
##  $ cie10_causa_id               : chr  "P22" "J18" "P91" "P22" ...
##  $ cie10_clasificacion          : chr  "Dificultad respiratoria del recién nacido" "Neumonía, organismo no especificado" "Otras alteraciones cerebrales del recién nacido" "Dificultad respiratoria del recién nacido" ...
##  $ sexo_id                      : int  1 1 1 2 1 1 1 1 2 1 ...
##  $ Sexo                         : chr  "masculino" "masculino" "masculino" "femenino" ...
##  $ muerte_materna_id            : chr  "" NA "" NA ...
##  $ muerte_materna_clasificacion : chr  NA NA NA NA ...
##  $ grupo_edad                   : chr  "01.De a 0  a 14 anios" "01.De a 0  a 14 anios" "01.De a 0  a 14 anios" "01.De a 0  a 14 anios" ...
##  $ cantidad                     : int  22 1 1 1 1 1 1 2 2 1 ...
# eliminamos las variables cie10_causa_id, muerte_materna_id y muerte_materna_clasificacion que no vamos a usar
defunciones$cie10_causa_id = NULL
defunciones$cie10_clasificacion = NULL
defunciones$muerte_materna_id = NULL
defunciones$muerte_materna_clasificacion = NULL

Podemos observar que en este archivo las edades están agrupadas de en grupos amplios que no coinciden con los que utiliza generalmente el INDEC (quinquenales).

Si observamos el documento “Procesamiento de proyecciones de población de Argentina 2010-2040 (INDEC)”), podemos ver que los grupos utilizados en las proyecciones de población son quinquenales, finalizando en el grupo “100 y más”.

Observamos los grupos etarios del archivo de defunciones:

unique(defunciones$grupo_edad)
## [1] "01.De a 0  a 14 anios" "02.De 15 a 34 anios"   "03.De 35 a 54 anios"  
## [4] "04.De 55 a 74 anios"   "05.De 75 anios y mas"  "06.Sin especificar"

Constatamos que son diferentes, por lo que tendremos que reagrupar las edades del archivo de población.

3- Procesamiento de los datos de población

En primer lugar vamos a descargar las proyecciones con el procesamiento realizado en el ejercicio anterior. El archivo resultante está alojado en el repositorio de GitHub, por lo que podemos descargarlo.

library(readr)
url = "https://raw.githubusercontent.com/agsantoro/VisualizacionDatos2023/refs/heads/main/poblacion_prov.csv"
download.file(url,dest="poblacion.csv")
poblacion = read_csv("poblacion.csv") %>% as.data.frame()

Observamos los grupos de edad de ambos archivos y reagrupamos las edades en el de población.

unique(poblacion$edad)
##  [1] "0-4"       "5-9"       "10-14"     "15-19"     "20-24"     "25-29"    
##  [7] "30-34"     "35-39"     "40-44"     "45-49"     "50-54"     "55-59"    
## [13] "60-64"     "65-69"     "70-74"     "75-79"     "80-84"     "85-89"    
## [19] "90-94"     "95-99"     "100 y más"
unique(defunciones$grupo_edad)
## [1] "01.De a 0  a 14 anios" "02.De 15 a 34 anios"   "03.De 35 a 54 anios"  
## [4] "04.De 55 a 74 anios"   "05.De 75 anios y mas"  "06.Sin especificar"
grupos = unique(poblacion$edad)

poblacion$edad[poblacion$edad %in% grupos[1:3]] = "01.De a 0  a 14 anios"
poblacion$edad[poblacion$edad %in% grupos[4:7]] = "02.De 15 a 34 anios"
poblacion$edad[poblacion$edad %in% grupos[8:11]] = "03.De 35 a 54 anios"
poblacion$edad[poblacion$edad %in% grupos[12:15]] = "04.De 55 a 74 anios"
poblacion$edad[poblacion$edad %in% grupos[16:21]] = "05.De 75 anios y mas"

Comprobamos que tengamos la misma clasificación en ambos archivos:

unique(poblacion$edad)
## [1] "01.De a 0  a 14 anios" "02.De 15 a 34 anios"   "03.De 35 a 54 anios"  
## [4] "04.De 55 a 74 anios"   "05.De 75 anios y mas"
unique(defunciones$grupo_edad)
## [1] "01.De a 0  a 14 anios" "02.De 15 a 34 anios"   "03.De 35 a 54 anios"  
## [4] "04.De 55 a 74 anios"   "05.De 75 anios y mas"  "06.Sin especificar"

La única diferencia observada es que en el archivo de defunciones tenemos muertes de edad sin especificar, mientras que en las proyecciones de población naturalmente esta categoría no existe.

Sumarizamos el dataset de poblaciones que reducir las filas

poblacion = poblacion %>% group_by(ano,juri,juri_nombre,sexo_codigo,sexo_nombre,edad) %>% summarise(poblacion=sum(poblacion))
colnames(poblacion)
## [1] "ano"         "juri"        "juri_nombre" "sexo_codigo" "sexo_nombre"
## [6] "edad"        "poblacion"

4- Cálculo de tasas de mortalidad

En primer lugar vamos a seleccionar y renombrar columnas del data frame de defunciones para que los nombres de las columnas coincidan en ambas fuentes.

colnames(poblacion)
## [1] "ano"         "juri"        "juri_nombre" "sexo_codigo" "sexo_nombre"
## [6] "edad"        "poblacion"
defunciones = defunciones %>% dplyr::select(ano = anio, 
                                            juri = jurisdiccion_de_residencia_id,
                                            sexo_codigo = sexo_id,
                                            edad = grupo_edad,
                                            cantidad)

head(defunciones)
##     ano juri sexo_codigo                  edad cantidad
## 1  2014   34           1 01.De a 0  a 14 anios       22
## 4  2016   94           1 01.De a 0  a 14 anios        1
## 5  2012   90           1 01.De a 0  a 14 anios        1
## 8  2021   62           2 01.De a 0  a 14 anios        1
## 10 2016   14           1 01.De a 0  a 14 anios        1
## 11 2017   86           1 01.De a 0  a 14 anios        1

También debemos incluir los datos del total del país y ambos sexos en el archivo de defunciones, que no tiene información agregada.

defunciones = rbind(
    defunciones,
    defunciones %>% mutate(juri=1))

defunciones = rbind(
    defunciones,
    defunciones %>% mutate(sexo_codigo=0))

Para que el archivo quede preparado, sólo nos queda utilizar el comando expand.grid para que contenga todas las combinaciones posibles.

grid = list(
  ano=unique(defunciones$ano),
  juri=unique(defunciones$juri),
  edad=unique(defunciones$edad),
  sexo_codigo=unique(defunciones$sexo_codigo)
)

grid = expand.grid(grid)

defunciones = left_join(grid,defunciones)
defunciones[is.na(defunciones)] = 0

# agrupamos para volver a sumarizar la tabla luego de todos los cambios
defunciones = defunciones %>% group_by(ano,juri,sexo_codigo,edad) %>% 
                              summarise(cantidad=sum(cantidad))

Ahora vamos a realizar un loop para ir recorriendo cada año, jurisdicción y sexo y calculando las tasas brutas y ajustadas con epitools.

library(epitools)

# convertimos las variables de código en numéricas para que puedan vincularse sin problema
poblacion$juri = as.numeric(poblacion$juri)
poblacion$sexo_codigo = as.numeric(poblacion$sexo_codigo)

# definimos la población total de Argentina en 2020 como población standard
poblacion_standard = poblacion$poblacion[poblacion$ano=="2020" &
                                           poblacion$sexo_nombre=="Ambos sexos" &
                                           poblacion$juri=="1"]

# creamos un data frame vacío donde se van a ir agregando los indicadores calculados
tasas_resultado = data.frame()

for (a in unique(defunciones$ano)) { # recorremos los años
  for (j in unique(defunciones$juri[defunciones$juri %in% 1:94])) { # dentro de cada jurisdicción, recorremos las jurisdicciones
    for (s in 0:2) { #dentro de cada jurisdicción, recorremos las categorías de sexo
      def_data = defunciones[defunciones$ano == a &
                             defunciones$juri == j &
                             defunciones$sexo_codigo == s,] %>% left_join(poblacion) # creamos un data frame con la información del año / jurisdicción / sexo activos
      
      defunciones_n = sum(def_data$cantidad) # calculamos el total de defunciones
      tasa_cruda = sum(def_data$cantidad)/sum(def_data$poblacion[is.na(def_data$poblacion)==F]) * 100000 # calculamos la tasa cruda
      
      def_data = def_data[def_data$edad!="06.Sin especificar",] # eliminamos la fila de edad sin especificar para cumplir con el modelo de datos que utliza la librería epitools
      
      # ahora creamos el dataset para anexar en esta vuelta del lopp
      ano = first(def_data$ano) # año
      juri_codigo = first(def_data$juri) # código de la jurisdicción
      juri_nombre = first(def_data$juri_nombre) # nombre de la jurisdicción
      sexo_codigo = first(def_data$sexo_codigo) # código de sexo
      sexo_nombre = first(def_data$sexo_nombre) # nombre de sexo
      
      # usamos la función ageadjust.direct para ajustar las tasas
      tasas = epitools::ageadjust.direct(
        count = def_data$cantidad, # en count se indica la cantidad de defunciones
        pop = def_data$poblacion, # en pop la población
        stdpop = poblacion_standard, # en stdpop la población utilizada como standard
        conf.level = .95 # en conf.level el nivel de confianza seleccionado para la estimación de los intervalos de confianza
      ) *100000
      
      # ordenamos todos los resultados en un data frame y lo añadimos a resultados
      
      append = data.frame(
        ano,
        juri_codigo,
        juri_nombre,
        sexo_codigo,
        sexo_nombre,
        defunciones_n,
        tasa_cruda,
        tasas[1],
        tasas[2],
        tasas[3],
        tasas[4]
      )
      
      colnames(append)[8:11] = names(tasas)
      rownames(append) = 1
      tasas_resultado = rbind(
        tasas_resultado,
        append 
      ) %>% arrange(juri_codigo,sexo_codigo)
    }
  }  
}

Visualizamos los resultados

library(DT)
DT::datatable(tasas_resultado, rownames = F)

 

 

Referencias

Aragon, Tomas J. 2020. Epitools: Epidemiology Tools. https://CRAN.R-project.org/package=epitools.
R Core Team. 2019. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org.
Wickham, Hadley, Romain François, Lionel Henry, Kirill Müller, and Davis Vaughan. 2023. Dplyr: A Grammar of Data Manipulation. https://CRAN.R-project.org/package=dplyr.
Wickham, Hadley, Jim Hester, and Jennifer Bryan. 2022. Readr: Read Rectangular Text Data. https://CRAN.R-project.org/package=readr.
Xie, Yihui, Joe Cheng, and Xianying Tan. 2023. DT: A Wrapper of the JavaScript Library ’DataTables’. https://CRAN.R-project.org/package=DT.