Cambios en la población adulto mayor entre los censos 2017 y 2024

Utilizo tablas y mapas basados en el paquete chilemapas para mostrar los cambios en la población adulto mayor entre los censos 2017 y 2024 en Chile.
Author

Mauricio “Pachá” Vargas S.

Published

December 10, 2025

Si esta publicación te resulta útil, te agradecería que hicieras una pequeña donación en Buy Me a Coffee. La utilizaré para continuar con mis iniciativas de código abierto.

Puedes enviarme preguntas para el blog utilizando este formulario y suscribirse para recibir un correo electrónico cuando haya una nueva publicación.

Después de procesar los datos del Censo 2024 de Población y Viviendas en Chile y corregir los códigos territoriales, procedo a utilizar tablas y mapas basados en el paquete chilemapas para mostrar los cambios en la población adulto mayor entre los censos 2017 y 2024 en Chile.

El código para procesar las tablas censales y generar los estadísticos se encuentra en: https://github.com/pachadotdev/blog-materials/tree/main/2025/12/10/adulto-mayor-censo.

Los datos que uso corresponden a la tabla con el diccionario corregido que dejé disponible en: https://github.com/pachadotdev/censo2024-duckdb

Carga de paquetes y creación de la tabla de población por edad y sexo y región:

if (!require("dplyr")) install.packages("dplyr")
if (!require("duckdb")) install.packages("duckdb")
if (!require("chilemapas")) install.packages("chilemapas")
if (!require("ggplot2")) install.packages("ggplot2")

library(dplyr)
library(duckdb)
library(chilemapas)
library(ggplot2)

con <- dbConnect(duckdb::duckdb(), dbdir = "~/Documents/censo2024-duckdb/censo2024_corregido.duckdb", read_only = FALSE)

dbListTables(con)

tbl(con, "codigos_personas") |>
    filter(nombre_variable == "sexo")

edad_por_region <- tbl(con, "personas") |>
    mutate(
        edad = case_when(
            edad >= 0 & edad <= 4  ~ "0 a 4",
            edad >= 5 & edad <= 9  ~ "5 a 9",
            edad >= 10 & edad <= 14 ~ "10 a 14",
            edad >= 15 & edad <= 19 ~ "15 a 19",
            edad >= 20 & edad <= 24 ~ "20 a 24",
            edad >= 25 & edad <= 29 ~ "25 a 29",
            edad >= 30 & edad <= 34 ~ "30 a 34",
            edad >= 35 & edad <= 39 ~ "35 a 39",
            edad >= 40 & edad <= 44 ~ "40 a 44",
            edad >= 45 & edad <= 49 ~ "45 a 49",
            edad >= 50 & edad <= 54 ~ "50 a 54",
            edad >= 55 & edad <= 59 ~ "55 a 59",
            edad >= 60 & edad <= 64 ~ "60 a 64",
            edad >= 65 & edad <= 69 ~ "65 a 69",
            edad >= 70 & edad <= 74 ~ "70 a 74",
            edad >= 75 & edad <= 79 ~ "75 a 79",
            edad >= 80 & edad <= 84 ~ "80 a 84",
            edad >= 85 & edad <= 89 ~ "85 a 89",
            edad >= 90 & edad <= 94 ~ "90 a 94",
            edad >= 95 & edad <= 99 ~ "95 a 99",
            edad >= 100              ~ "100 o mas",
            TRUE                     ~ NA_character_
        )
    ) |>
    filter(!is.na(edad)) |>
    mutate(
        sexo = case_when(
            sexo == 1 ~ "hombre",
            sexo == 2 ~ "mujer",
            TRUE       ~ NA_character_
        )
    ) |>
    mutate(region = substr(comuna, 1, 2)) |>
    group_by(region, edad, sexo) |>
    summarise(poblacion2024 = n()) |>
    inner_join(
        tbl(con, "codigos_territoriales"),
        by = c("region" = "codigo_territorial")
    ) |>
    collect()

Estos resultados se pueden unir a los del censo 2027, la misma tabla de población por edad, sexo y región es parte del paquete chilemapas como censo_2017_comunas.

edad_por_region <- edad_por_region |>
  filter(!is.na(edad)) |>
  mutate(
    edad = factor(
      edad,
      levels = c(
        "0 a 4", "5 a 9", "10 a 14", "15 a 19", "20 a 24",
        "25 a 29", "30 a 34", "35 a 39", "40 a 44", "45 a 49",
        "50 a 54", "55 a 59", "60 a 64", "65 a 69", "70 a 74",
        "75 a 79", "80 a 84", "85 a 89", "90 a 94", "95 a 99",
        "100 o mas"
      )
    ),
    sexo = factor(
      sexo,
      levels = c("hombre", "mujer")
    )
  ) |>
  inner_join(
    censo_2017_comunas |>
        mutate(region = substr(codigo_comuna, 1, 2)) |>
        rename(poblacion2017 = poblacion) |>
        group_by(region, edad, sexo) |>
        summarise(poblacion2017 = sum(poblacion2017)),
    by = c("region", "edad", "sexo")
  ) |>
  select(region, nombre_region = territorio, region, edad, sexo, poblacion2017, poblacion2024)

Una vez unidos los datos de ambos censos, se puede calcular el cambio en número y porcentaje en la población adulto mayor. La tabla anterior la armé con un criterio amplio por si alguien más adelante quiere hacer análisis por grupos de edad más detallados.

edad_por_region <- edad_por_region |>
    mutate(
        edad2 = case_when(
            edad %in% c(
                "65 a 69", "70 a 74", "75 a 79", "80 a 84",
                "85 a 89", "90 a 94", "95 a 99", "100 o mas"
            ) ~ "adulto mayor",
            TRUE ~ "no adulto mayor"
        )
    ) |>
    group_by(region, nombre_region, edad2, sexo) |>
    summarise(
        poblacion2017 = sum(poblacion2017),
        poblacion2024 = sum(poblacion2024)
    ) |>
    mutate(
        n_cambio = poblacion2024 - poblacion2017,
        p_cambio = (n_cambio / poblacion2017) * 100
    )

Regiones con mayor aumento de adultos mayores hombre/mujer:

edad_por_region |>
    filter(edad2 == "adulto mayor") |>
    arrange(desc(p_cambio)) |>
    head(10)

# A tibble: 10 × 6
   codigo_region nombre_region                     edad2 sexo  n_cambio p_cambio
   <chr>         <chr>                             <chr> <fct>    <dbl>    <dbl>
 1 01            Tarapacá                          adul… mujer     5759     44.5
 2 01            Tarapacá                          adul… homb…     4684     42.1
 3 06            Libertador General Bernardo O'Hi… adul… mujer    22974     41.1
 4 02            Antofagasta                       adul… mujer     9543     38.7
 5 02            Antofagasta                       adul… homb…     7475     38.7
 6 07            Maule                             adul… mujer    25395     38.5
 7 06            Libertador General Bernardo O'Hi… adul… homb…    18123     36.8
 8 04            Coquimbo                          adul… mujer    17327     36.6
 9 03            Atacama                           adul… mujer     5215     35.9
10 04            Coquimbo                          adul… homb…    13742     35.4

Mapas de cambio absoluto y porcentual de adultos mayores por región (uso una función para no repetir código):

edad_por_region <- edad_por_region |>
    select(region, nombre_region, edad2, sexo, n_cambio, p_cambio)

edad_por_region <- generar_regiones() |>
    select(codigo_region, geometry) |>
    left_join(
        edad_por_region,
        by = c("codigo_region" = "region")
    )

edad_por_region |>
    filter(is.na(p_cambio))

g <- function(s = "hombre", v = "n_cambio") {
    g2 <- ggplot() +
        geom_sf(
            data = filter(edad_por_region, sexo == s),
            aes(fill = !!sym(v), geometry = geometry),
            color = "black",
            size = 0.1
        ) +
        labs(
            title = sprintf("Adulto mayor  - %s - %s",
                stringr::str_to_title(s),
                ifelse(v == "n_cambio", "Cambio absoluto", "Cambio porcentual")
                ),
        ) +
        theme_minimal() + 
        coord_sf(xlim = c(-75, -66))

    if (v == "n_cambio") {
        my_pal <- tintin::tintin_clrs(option = "the_blue_lotus")[2:1]

        g2 + scale_fill_gradient2(my_pal[1], low = "white", high = my_pal[2],
        na.value = "lightgrey")
    } else {
        my_pal <- tintin::tintin_clrs(option = "the_seven_crystal_balls")[2:1]

        g2 + scale_fill_gradient2(low = my_pal[1], mid = "white", high = my_pal[2],
        na.value = "lightgrey")
    }
}

gnh <- g("hombre", "n_cambio")
gnm <- g("mujer", "n_cambio")
gph <- g("hombre", "p_cambio")
gpm <- g("mujer", "p_cambio")

dout <- list(
  gnh = gnh,
  gnm = gnm,
  gph = gph,
  gpm = gpm
)

saveRDS(dout, file = "adulto_mayor_censo.rds", compress = "xz")

dout$gnh

dout$gnm

dout$gph

dout$gpm

Resultados: