1 Marco teórico y fuentes de información

De acuerdo con Newell (1988), la nupcialidad abarca los fenómenos demográficos de matrimonio (o unión), divorcio, viudez y rematrimonio. El interés central de la demografía está en la edad a la primera unión, porque la exposición al riesgo de concepción, y con ello la fecundidad, aumenta sustancialmente cuando la mujer vive en unión conyugal.

1.1 Fuentes de datos

  • Registros administrativos: son la fuente ideal para medir eventos, pero en muchos países hay subregistro por uniones consensuales o separaciones fuera de marcos legales. Además, registran matrimonios (eventos), no personas, por lo que mezclan primeros matrimonios y rematrimonios.
  • Encuestas (longitudinales o transversales) y censos: son la segunda mejor opción cuando el registro administrativo (registro civil) es deficiente. Aportan información transversal (stock) sobre el estado conyugal por grupos de edad y son la base de los métodos indirectos como el SMAM.

1.2 Categorías mínimas recomendadas por la ONU para los censos

  1. Soltero (nunca casado)
  2. Casado
  3. Viudo (no vuelto a casar)
  4. Divorciado (no vuelto a casar)
  5. Casado otra vez / vuelto a casar

¿Por qué distinguir entre solteros (nunca casados) y casados por primera vez? Porque solo así se puede estimar la edad a la primera unión y medir cómo afecta a la fecundidad, en particular al primer hijo nacido vivo.

Nota para América Latina. Las uniones consensuales son una forma de primera unión muy extendida. Conviene definir con claridad qué significa “soltero” en el análisis: nunca casado legalmente o nunca unido (ni casado ni en unión libre). El SMAM resultante cambia de forma importante según la definición adoptada, así que debe declararse en toda comparación.


2 Medidas directas de nupcialidad

Sea \(M_t\) el número de matrimonios registrados en el año \(t\).

2.1 Tasa bruta de nupcialidad (CMR, Crude Marriage Rate)

Mide el volumen general de matrimonios ocurridos durante el año \(t\) respecto de la población total (todas las edades, 0 a 100+). Se llama bruta (cruda) porque su valor está afectado por la estructura por edad de la población:

\[ \text{CMR}_t = \frac{M_t}{P_t} \times 1000 \]

2.2 Tasa general de nupcialidad (GMR, General Marriage Rate)

Elimina del denominador a la población no expuesta al riesgo de casarse. Siguiendo a Newell (1988), el denominador son las mujeres de 15 años o más no casadas (solteras, viudas y divorciadas); en otras fuentes también se calcula para hombres o para ambos sexos:

\[ \text{GMR}_t = \frac{M_t}{\text{Mujeres no casadas}_{15+,\,t}} \times 1000 \]

2.3 Tasas específicas de primer matrimonio y tasa global

Para controlar la edad y aislar los primeros matrimonios se usan tasas por grupo quinquenal \([x, x+n)\):

\[ m_x = \frac{M^{(1)}_{x,x+n}}{P_{x,x+n}}, \qquad \text{TGPM} = n \sum_x m_x, \qquad \bar{a} = \frac{\sum_x \left(x + \tfrac{n}{2}\right) m_x}{\sum_x m_x} \]

donde \(M^{(1)}\) son los primeros matrimonios, \(\text{TGPM}\) es la tasa global de primeros matrimonios (proporción de una cohorte sintética que se casa al menos una vez, en ausencia de mortalidad y migración) y \(\bar{a}\) es la edad media al primer matrimonio.

# Ejemplo numérico ilustrativo (cifras ficticias)
M_t       <- 570000    # matrimonios en el año
P_t       <- 125000000 # población total a mitad de año
MNC_15    <- 26000000 # mujeres de 15+ no casadas

CMR <- M_t / P_t * 1000
GMR <- M_t / MNC_15 * 1000
data.frame(Indicador = c("CMR", "GMR"), `Por mil` = round(c(CMR, GMR), 2),
           check.names = FALSE) %>% kable(caption = "Tasas directas (cifras ficticias)")
Tasas directas (cifras ficticias)
Indicador Por mil
CMR 4.56
GMR 21.92

Nota La GMR es siempre mayor que la CMR porque su denominador es menor. Además, es menos sensible a la estructura por edad y estado civil de la población.


3 Edad media al matrimonio: método indirecto de Hajnal (SMAM)

El SMAM (Singulate Mean Age at Marriage, Hajnal 1953) estima la edad media a la primera unión entre quienes se casan antes de los 50 años usando un solo corte transversal de proporciones de solteros por edad.

Es, en muchos aspectos, una medida análoga a la tasa global de fecundidad (TGF), pues comparte sus supuestos de construcción:

  1. está estandarizada por edad;
  2. es una medida de período;
  3. se describe mediante una cohorte sintética;
  4. usa la proporción de solteros (nunca casados) por edad, no los casados clasificados por edad.

Interpretación. Más que como la “edad media al matrimonio”, el SMAM se entiende como el tiempo medio vivido en soltería por quienes llegan a casarse. Se obtiene dividiendo el total de años vividos en soltería entre el número de personas que eventualmente se casan.

3.1 Idea central

Sea \(S(a)\) la proporción de solteros a la edad exacta \(a\) en una cohorte sintética de 100 personas. El área bajo la curva \(S(a)\) entre 0 y 50 años equivale al total de años-persona vividos en soltería antes de los 50:

\[ \text{TASV}_{50} = \int_0^{50} S(a)\,da \;\approx\; 15 + 5\sum_{a=15\text{-}19}^{45\text{-}49} S_a \qquad (\text{por persona}) \]

Con una cohorte de 100 personas y \(S_a\) en porcentaje, los 15 años previos aportan \(15\times 100 = 1500\) años y la fórmula queda:

\[ \text{TASV}_{50} = 1500 + 5\sum_{a=15\text{-}19}^{45\text{-}49} S_a^{\%} \]

Se supone que quienes nunca se casan vivieron los 50 años en soltería, y su proporción \(PS_{50}\) se estima por interpolación de los grupos 45-49 y 50-54:

\[ PS_{50} = \frac{S_{45\text{-}49}^{\%} + S_{50\text{-}54}^{\%}}{2} \]

3.2 Algoritmo paso a paso

Paso Cantidad Fórmula
1 Años solteros vividos antes de los 15 por 100 personas \(A_{0\text{-}15} = 15 \times 100 = 1500\)
2 Proporción de solteros (nunca casados) por grupo \(S_a = \dfrac{\text{Solteros}_{x,x+n}}{\text{Población}_{x,x+n}}\)
3 Tiempo vivido en soltería en cada grupo \(S_a \times n\), con \(n = 5\)
4 Tiempo vivido en soltería entre las edades exactas 15 y 50 \(5\sum_{a=15}^{45} S_a^{\%}\)
5 Total de años solteros vividos antes de los 50 \(\text{TASV}_{50} = 1500 + 5\sum_{a=15}^{45} S_a^{\%}\)
6 Porcentaje que permanece soltero a los 50 \(PS_{50} = \tfrac{1}{2}\left(S_{45\text{-}49}^{\%} + S_{50\text{-}54}^{\%}\right)\)
7 Años solteros de quienes sí se casan \(M_e = \text{TASV}_{50} - 50 \times PS_{50}\)
8 Personas que se casan antes de los 50 \(NM_{50} = 100 - PS_{50}\)
9 SMAM \(\text{SMAM} = \dfrac{M_e}{NM_{50}}\)

En forma compacta, con proporciones \(s_a \in [0,1]\) y \(\bar{s}_{50} = \tfrac{1}{2}(s_{45\text{-}49}+s_{50\text{-}54})\):

\[ \text{SMAM} = \frac{15 + 5\sum_{a=15\text{-}19}^{45\text{-}49} s_a \;-\; 50\,\bar{s}_{50}}{1 - \bar{s}_{50}} \]

Nota de notación respecto de las notas de clase. En las notas compartidas en clase (pdf SMAN), \(PS_{50}\) se define ya multiplicado por 50 (años-persona), de modo que \(M_e = \text{TASV}_{50} - PS_{50}\), mientras que \(NM_{50}\) usa el promedio de solteros sin multiplicar. Aquí se separan las unidades: \(PS_{50}\) es el porcentaje de solteros a los 50 y el factor 50 aparece explícito en \(M_e = \text{TASV}_{50} - 50\,PS_{50}\). Las dos formas son equivalentes.

Supuestos adicionales y limitaciones. Además de los cuatro supuestos anteriores, se supone que:

  • la nupcialidad es estable en el tiempo, por lo que el corte transversal representa a una cohorte sintética;
  • la migración es nula o neutral respecto del estado civil;
  • la mortalidad de los solteros no difiere de la de los casados;
  • la proporción de solteros a los 50 años se estima por interpolación.

No olvidar, el SMAM es muy sensible a la definición de “soltero” y al nivel de soltería definitiva, por tanto, el calculo obtenido en clase, no necesariamente coincidirá con los de INEGI.


4 Función en R para el cálculo del SMAM

La función recibe las 8 proporciones de solteros (0-1) de los grupos 15-19, 20-24, …, 45-49 y 50-54, valida los datos y devuelve todos los componentes del cálculo.

calcular_smam <- function(s) {
  # s: proporciones de solteros (0-1) en los grupos
  #    15-19, 20-24, 25-29, 30-34, 35-39, 40-44, 45-49, 50-54
  stopifnot(is.numeric(s), length(s) == 8, !anyNA(s), all(s >= 0 & s <= 1))

  A_0_15 <- 15 * 100                          # Paso 1
  TASV50 <- A_0_15 + 5 * sum(s[1:7] * 100)    # Paso 2: grupos 15-19 ... 45-49
  PS50   <- 100 * mean(s[7:8])                # Paso 3: promedio 45-49 y 50-54
  Me     <- TASV50 - 50 * PS50                # Paso 4
  NM50   <- 100 - PS50                        # Paso 5

  list(TASV50 = TASV50, PS50 = PS50, Me = Me, NM50 = NM50,
       SMAM = Me / NM50)                      # Paso 6
}

En la práctica el insumo son conteos de solteros (nunca casados) y de población por grupo, como en el paso 2. La siguiente función los convierte en proporciones y llama a calcular_smam(). El auxiliar prop_15_19() sirve cuando la fuente trae grupos más finos (por ejemplo, 15-17 y 18-19) y hay que formar el grupo quinquenal 15-19.

smam_desde_conteos <- function(solteros, poblacion) {
  # Vectores de 8 grupos: 15-19, ..., 50-54
  stopifnot(length(solteros) == 8, length(poblacion) == 8,
            all(poblacion > 0), all(solteros <= poblacion))
  calcular_smam(solteros / poblacion)
}

# Proporción de solteros del grupo 15-19 a partir de 15-17 y 18-19
prop_15_19 <- function(solt_15_17, pob_15_17, solt_18_19, pob_18_19) {
  (solt_15_17 + solt_18_19) / (pob_15_17 + pob_18_19)
}

5 Ejercicio real: SMAM por entidad federativa y sexo (Censo 2020)

Esta sección reproduce con datos reales los cálculos de la pestaña SMAN del libro de excel visto en clase SMAN_censo2020.xlsx, pero para cada entidad federativa y cada sexo, de las pestañas originales tal cual las publica INEGI, en lugar de solo el total nacional de hombres que trae la el ejemplo visto en clase.

Sobre las pestañas del libro de excel. Contiene dos tabulados del Censo de Población y Vivienda 2020 que provien del cuestionario básico:

  • pestaña 01: población de 12 años y más por tamaño de localidad, sexo y grupos quinquenales de edad, según situación conyugal;
  • pestaña 02: el mismo tabulado por entidad federativa.

Los estados están en la pestaña 02, que además es de donde proceden los datos pegados en la pestaña SMAN (la columna A dice “Entidad federativa”). Por eso el análisis por estado usa la 02. Se importan ambas pestañas y el mismo código se aplica a la 01 al final del ejercicio.

OJO AQuÍ El archivo SMAN_censo2020.xlsx debe estar en la misma carpeta que este .Rmd. Si está en otra ruta, se cambia el parámetro ruta_excel del encabezado YAML.

5.1 Importar los datos a R

Cada pestaña tiene 9 filas de encabezado (título, fecha y encabezados de varios niveles), así que se saltan con skip = 9 y se asignan los nombres de columna a mano. Cada bloque de una unidad (estado o tamaño de localidad) tiene 51 filas: 3 sexos (Total, Hombres, Mujeres) × 17 filas (Total más 16 grupos de edad, de 12-14 a 85 y más).

library(readxl)

ruta_excel <- params$ruta_excel
excel_sheets(ruta_excel)
## [1] "Índice" "01"     "02"     "SMAN"
nombres_cols <- c("unidad", "sexo", "grupo_edad", "poblacion",
                  "soltera", "casada_civil", "casada_religiosa",
                  "casada_civil_religiosa", "union_libre", "separada",
                  "divorciada", "viuda", "no_especificado")

leer_tabulado <- function(ruta, hoja) {
  read_excel(ruta, sheet = hoja, skip = 9, col_names = nombres_cols,
             col_types = c(rep("text", 3), rep("numeric", 10))) %>%
    filter(!is.na(unidad))
}

datos_01 <- leer_tabulado(ruta_excel, "01")   # por tamaño de localidad
datos_02 <- leer_tabulado(ruta_excel, "02")   # por entidad federativa

5.2 Leer la pestaña y revisar su estructura

revisar <- function(d) {
  tibble(
    unidades = n_distinct(d$unidad),
    filas = nrow(d),
    `filas por unidad y sexo` = d %>% count(unidad, sexo) %>% pull(n) %>%
      unique() %>% paste(collapse = ", "),
    # las 9 categorías conyugales deben sumar la población de cada fila
    `filas donde la suma no cuadra` = sum(rowSums(d[, 5:13]) != d$poblacion)
  )
}

bind_rows(`01 (tamaño de localidad)` = revisar(datos_01),
          `02 (entidad federativa)`  = revisar(datos_02),
          .id = "pestaña") %>%
  kable(caption = "Revisión de los tabulados importados")
Revisión de los tabulados importados
pestaña unidades filas filas por unidad y sexo filas donde la suma no cuadra
01 (tamaño de localidad) 15 765 17 0
02 (entidad federativa) 33 1683 17 0
rmarkdown::paged_table(head(datos_02, 34))

5.3 Método SMAN como lo vimos en clase (archivo excel)

La pestaña SMAN aplica una variante del SMAM de Hajnal con ventana de 12 a 60 años (la edad mínima del tabulado es 12). Para cada grupo de edad \(a\) (de 12-14 a 85 y más) de cada unidad y sexo:

  1. Distribuir los “No especificado” de forma proporcional entre las ocho categorías conyugales (columnas E:L del excel), con \(P_a\) la población del grupo y \(NE_a\) los no especificados:

\[ x^{*}_{c,a} = x_{c,a} + \frac{x_{c,a}}{P_a - NE_a}\, NE_a, \qquad \sum_c x^{*}_{c,a} = P_a \]

  1. Proporción de solteros (columna \(Q\)) y años vividos en soltería del grupo (columna \(S\), “\(_{n}L_x\) soltería”), con amplitud \(n_a = 3\) para 12-14 y \(n_a = 5\) en los demás grupos:

\[ Q_a = \frac{x^{*}_{\text{soltera},a}}{P_a}, \qquad _nL_x = n_a\, Q_a \]

  1. Parámetros (columnas U:W). Se supone que todos son solteros hasta los 12 años (“fin del celibato”, \(C_{12}=12\)):
Parámetro (celda) Definición Fórmula
Última chance, \(C_{60}\) (W24) Proporción que sigue soltera a los 60 \(\tfrac{1}{2}\left(Q_{55\text{-}59} + Q_{60\text{-}64}\right)\)
Calendario de \(C_{60}\), \(T_{60}\) (W25) Años solteros de quienes nunca se unen \(60\, C_{60}\)
\(T_0\) (W29) Años solteros acumulados \(12 + \sum_{a=12\text{-}14}^{75\text{-}79} nL_a\)
Casados, \(nL\) (W31) Años solteros de quienes sí se unen \(T_0 - T_{60}\)
Los casados (W27) Denominador \(100 - T_{60}\)
SMAM (W33) Edad media a la primera unión \(\dfrac{T_0 - T_{60}}{100 - T_{60}} \times 100\)

Aquí “soltero” es la categoría Soltera(o) del tabulado, que es excluyente de casada(o), unión libre, separada(o), divorciada(o) y viuda(o). Por eso el indicador mide la edad a la primera unión de cualquier tipo, incluida la unión libre.

5.3.1 Observaciones sobre la hoja

Al generar el código que replica las fórmulas saltan tres puntos que conviene mencionar. Por eso el código calcula la réplica exacta de la hoja (SMAM_hoja) más dos variantes de contraste:

  1. Rango de \(T_0\). W29 suma S22:S35 (hasta 75-79), pero su etiqueta dice “de 12 a 85 y más”. Las filas 36 y 37 (80-84 y 85 y más) no entran.
  2. Unidades del denominador. W27 = 100 - W25 resta de 100 un valor en años (\(60\,C_{60}\)), no un porcentaje. Con \(C_{60}\) como proporción, el denominador consistente sería \(1 - C_{60}\) (o \(100\,(1 - C_{60})\) en porcentaje). Variante SMAM_den_corr.
  3. Ventana de suma. \(C_{60}\) ya “congela” a quienes siguen solteros a los 60 años, pero \(T_0\) acumula soltería hasta los 79. El SMAM de Hajnal truncado a 60 sumaría solo hasta el grupo 55-59:

\[ \text{SMAM}_{60} = \frac{\left(12 + \sum_{a=12\text{-}14}^{55\text{-}59} nL_a\right) - 60\, C_{60}}{1 - C_{60}} \]

Variante 1 SMAM_hajnal60.

5.4 Cálculos de la hoja (A22:W37) para cada entidad y sexo

Las funciones siguen la hoja columna por columna. calc_bloque() reproduce el bloque A22:S37 de una unidad y sexo, y parametros_smam() reproduce los parámetros U:W.

cols_estado <- c("soltera", "casada_civil", "casada_religiosa",
                 "casada_civil_religiosa", "union_libre", "separada",
                 "divorciada", "viuda")                      # columnas E:L de la hoja

# Bloque A22:S37 de una unidad y sexo (16 filas, de 12-14 a 85 y más)
calc_bloque <- function(d) {
  d <- d %>% mutate(D = poblacion - no_especificado)          # col. D: población sin "No especificado"
  for (v in cols_estado) {                                    # cols. E:L: reasignación proporcional
    d[[v]] <- d[[v]] + d[[v]] / d$D * d$no_especificado
  }
  d %>% mutate(
    A = rowSums(across(all_of(cols_estado))),                 # col. A: suma E:L (= población del grupo)
    P = A - soltera,                                          # col. P: entraron en unión (suma F:L)
    Q = soltera / A,                                          # col. Q: proporción de solteros
    R = if_else(grupo_edad == "12-14 años", 3, 5),            # col. R: amplitud del intervalo
    S = Q * R                                                 # col. S: nLx soltería
  )
}

# Parámetros U:W (y dos variantes de contraste)
parametros_smam <- function(b) {
  stopifnot(nrow(b) == 16)
  C12 <- 12                                                   # W22: fin del celibato
  C60 <- mean(b$Q[b$grupo_edad %in% c("55-59 años", "60-64 años")])   # W24
  T60 <- C60 * 60                                             # W25
  T0  <- sum(b$S[1:14]) + C12                                 # W29: S22:S35 + W22
  casados_nLx <- T0 - T60                                     # W31
  casados     <- 100 - T60                                    # W27
  tibble(
    C60 = C60, T60 = T60, T0 = T0,
    casados_nLx = casados_nLx, casados = casados,
    SMAM_hoja     = casados_nLx / casados * 100,              # W33 (réplica de la hoja)
    SMAM_den_corr = casados_nLx / (1 - C60),                  # solo corrige el denominador
    SMAM_hajnal60 = ((sum(b$S[1:10]) + C12) - T60) / (1 - C60) # Hajnal truncado a 60 años
  )
}

# Aplica ambas funciones a cada unidad y sexo
ejecutar_smam <- function(datos, sexos = c("Hombres", "Mujeres")) {
  detalle <- datos %>%
    filter(grupo_edad != "Total", sexo %in% sexos) %>%
    group_by(unidad, sexo) %>%
    group_modify(~ calc_bloque(.x)) %>%
    ungroup()
  resultados <- detalle %>%
    group_by(unidad, sexo) %>%
    group_modify(~ parametros_smam(.x)) %>%
    ungroup()
  list(detalle = detalle, resultados = resultados)
}

etiqueta_unidad <- function(x, quitar_clave = FALSE) {
  if (quitar_clave) x <- sub("^[0-9]{2} ", "", x)             # "09 Ciudad de México" -> "Ciudad de México"
  ifelse(x == "Estados Unidos Mexicanos", "Nacional", x)
}
niveles_edad <- datos_02 %>% filter(grupo_edad != "Total") %>%
  pull(grupo_edad) %>% unique()

res02 <- ejecutar_smam(datos_02)

detalle_ent <- res02$detalle %>%
  mutate(etiqueta = etiqueta_unidad(unidad, quitar_clave = TRUE))
resultados_ent <- res02$resultados %>%
  mutate(etiqueta = etiqueta_unidad(unidad, quitar_clave = TRUE))

Como ejemplo, el bloque A22:S37 para hombres, total nacional (el que aparece en la hoja):

detalle_ent %>%
  filter(unidad == "Estados Unidos Mexicanos", sexo == "Hombres") %>%
  select(grupo_edad, D, soltera:viuda, A, P, Q, R, S) %>%
  mutate(across(where(is.numeric), ~ round(.x, 4))) %>%
  rmarkdown::paged_table()

5.4.1 Validación contra la pestaña SMAN

Los valores calculados en R para hombres, total nacional, deben coincidir con los de las celdas W22:W33 del libro (valores en caché de Excel):

excel_ref <- c(C60 = 0.07438753739800508, T60 = 4.463252243880305,
               T0 = 30.740643281622525, casados_nLx = 26.27739103774222,
               casados = 95.5367477561197, SMAM_hoja = 27.505008967671284)

r_nac_h <- resultados_ent %>%
  filter(unidad == "Estados Unidos Mexicanos", sexo == "Hombres")

tibble(Parámetro  = names(excel_ref),
       Excel      = unname(excel_ref),
       R          = unlist(r_nac_h[names(excel_ref)], use.names = FALSE)) %>%
  mutate(Diferencia = R - Excel, Coincide = abs(Diferencia) < 1e-8) %>%
  kable(digits = 6, caption = "Validación: hombres, total nacional (R vs. Excel)")
Validación: hombres, total nacional (R vs. Excel)
Parámetro Excel R Diferencia Coincide
C60 0.074388 0.074388 0 TRUE
T60 4.463252 4.463252 0 TRUE
T0 30.740643 30.740643 0 TRUE
casados_nLx 26.277391 26.277391 0 TRUE
casados 95.536748 95.536748 0 TRUE
SMAM_hoja 27.505009 27.505009 0 TRUE

5.5 Resultados por entidad federativa y sexo

res_est <- resultados_ent %>% filter(unidad != "Estados Unidos Mexicanos")

resultados_ent %>%
  transmute(Entidad = etiqueta, Sexo = sexo,
            `C60 (%)` = 100 * C60, T0, T60,
            SMAM_hoja, SMAM_den_corr, SMAM_hajnal60) %>%
  mutate(across(where(is.numeric), ~ round(.x, 2))) %>%
  rmarkdown::paged_table()
res_ancho <- resultados_ent %>%
  select(etiqueta, sexo, SMAM_hoja) %>%
  pivot_wider(names_from = sexo, values_from = SMAM_hoja) %>%
  mutate(`Brecha (H - M)` = Hombres - Mujeres) %>%
  arrange(desc(Mujeres))

res_ancho %>%
  rename(Entidad = etiqueta) %>%
  mutate(across(where(is.numeric), ~ round(.x, 2))) %>%
  rmarkdown::paged_table()
nac <- resultados_ent %>% filter(unidad == "Estados Unidos Mexicanos")
smam_nac_h <- nac$SMAM_hoja[nac$sexo == "Hombres"]
smam_nac_m <- nac$SMAM_hoja[nac$sexo == "Mujeres"]

extremos <- res_est %>%
  group_by(sexo) %>%
  summarise(mayor = etiqueta[which.max(SMAM_hoja)], v_mayor = max(SMAM_hoja),
            menor = etiqueta[which.min(SMAM_hoja)], v_menor = min(SMAM_hoja),
            .groups = "drop")

A nivel nacional, el SMAM (réplica de la hoja) es de 27.5 años en hombres y 24.8 años en mujeres. Por entidad, el SMAM masculino va de 25.9 (Chiapas) a 30.7 (Ciudad de México), y el femenino de 23.1 (Chiapas) a 28.2 (Ciudad de México).

5.5.1 Efecto de las tres observaciones sobre la hoja

nac %>%
  transmute(Sexo = sexo,
            `Hoja (réplica)` = SMAM_hoja,
            `Solo denominador corregido` = SMAM_den_corr,
            `Hajnal truncado a 60` = SMAM_hajnal60) %>%
  kable(digits = 2, caption = "SMAM nacional según variante de cálculo")
SMAM nacional según variante de cálculo
Sexo Hoja (réplica) Solo denominador corregido Hajnal truncado a 60
Hombres 27.51 28.39 27.18
Mujeres 24.82 25.92 23.98
res_est %>%
  mutate(dif_hajnal60 = SMAM_hajnal60 - SMAM_hoja) %>%
  group_by(sexo) %>%
  summarise(`Dif. media` = mean(dif_hajnal60),
            `Dif. mínima` = min(dif_hajnal60),
            `Dif. máxima` = max(dif_hajnal60), .groups = "drop") %>%
  kable(digits = 2, caption = "SMAM Hajnal-60 menos SMAM de la hoja, entre entidades (años)")
SMAM Hajnal-60 menos SMAM de la hoja, entre entidades (años)
sexo Dif. media Dif. mínima Dif. máxima
Hombres -0.35 -0.55 -0.16
Mujeres -0.77 -1.15 -0.43

5.6 La gráfica de la hoja, por entidad y sexo

La gráfica de la pestaña SMAN es una línea con la proporción de solteros por edad, más una línea horizontal en 0.5. Sus categorías son las edades 1 a 12 (con proporción 1, porque todos son solteros antes de los 12 años) seguidas de los 16 grupos de edad de 12-14 a 85 y más.

colores_sexo   <- c(Hombres = "#d95f02", Mujeres = "#7570b3")
etiquetas_edad <- sub(" años", "", niveles_edad)               # "85 años y más" -> "85 y más"
niveles_x      <- c(as.character(1:12), etiquetas_edad)

# Serie de la gráfica: edades 1-12 con proporción 1 y luego Q por grupo de edad
datos_curva <- function(detalle) {
  previos <- expand_grid(distinct(detalle, etiqueta, sexo), x = as.character(1:12)) %>%
    mutate(y = 1)
  grupos <- detalle %>%
    transmute(etiqueta, sexo, x = sub(" años", "", grupo_edad), y = Q)
  bind_rows(previos, grupos) %>%
    mutate(x = factor(x, levels = niveles_x))
}

5.6.1 Total nacional (réplica de la gráfica de la hoja)

curva_nac <- datos_curva(detalle_ent %>% filter(unidad == "Estados Unidos Mexicanos"))

ggplot(curva_nac, aes(x = x, y = y, group = sexo, color = sexo)) +
  geom_hline(yintercept = 0.5, linetype = "dashed", color = "gray50") +
  geom_line(linewidth = 1) +
  geom_point(size = 1.4) +
  facet_wrap(~ sexo) +
  scale_color_manual(values = colores_sexo, guide = "none") +
  scale_y_continuous(limits = c(0, 1), breaks = seq(0, 1, 0.1)) +
  scale_x_discrete(breaks = c("1", "6", "12", "20-24", "30-34", "40-44",
                              "50-54", "60-64", "70-74", "85 y más")) +
  labs(title = "México 2020: proporción de solteros por edad y sexo",
       subtitle = "Réplica de la gráfica de la pestaña SMAN; la línea punteada marca 50%",
       x = "Edad o grupo de edad", y = "Proporción de solteros") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

5.6.2 Cada entidad federativa, hombres y mujeres

curva_ent <- datos_curva(detalle_ent %>% filter(unidad != "Estados Unidos Mexicanos"))

ggplot(curva_ent, aes(x = x, y = y, group = sexo, color = sexo)) +
  geom_hline(yintercept = 0.5, linetype = "dashed", color = "gray60") +
  geom_line(linewidth = 0.7) +
  facet_wrap(~ etiqueta, ncol = 6, labeller = label_wrap_gen(18)) +
  scale_color_manual(values = colores_sexo) +
  scale_y_continuous(limits = c(0, 1), breaks = c(0, 0.5, 1)) +
  scale_x_discrete(breaks = c("12", "25-29", "40-44", "55-59", "70-74")) +
  labs(title = "México 2020: proporción de solteros por edad, entidad y sexo",
       subtitle = "Línea punteada: 50% de solteros",
       x = "Edad o grupo de edad", y = "Proporción de solteros", color = "Sexo") +
  theme_minimal(base_size = 10) +
  theme(legend.position = "top",
        plot.title = element_text(face = "bold"),
        axis.text.x = element_text(angle = 60, hjust = 1, size = 7),
        strip.text = element_text(size = 8))

5.6.3 SMAM por entidad y sexo

Las líneas punteadas verticales marcan el SMAM nacional de cada sexo.

ggplot(res_est, aes(x = SMAM_hoja, y = reorder(etiqueta, SMAM_hoja), color = sexo)) +
  geom_path(aes(group = etiqueta), color = "gray75") +
  geom_point(size = 2.4) +
  geom_vline(data = nac, aes(xintercept = SMAM_hoja, color = sexo),
             linetype = "dashed", show.legend = FALSE) +
  scale_color_manual(values = colores_sexo) +
  labs(title = "SMAM por entidad federativa y sexo, Censo 2020",
       subtitle = "Réplica de la hoja SMAN; entidades ordenadas por el promedio de ambos sexos",
       x = "SMAM (años)", y = NULL, color = "Sexo") +
  theme_minimal(base_size = 11) +
  theme(legend.position = "top", plot.title = element_text(face = "bold"))

5.7 El mismo ejercicio por tamaño de localidad (pestaña 01)

La pestaña 01 tiene exactamente la misma estructura, solo que la unidad es el tamaño de localidad. Como el código no depende del tipo de unidad, se reutiliza sin cambios.

res01 <- ejecutar_smam(datos_01)

orden_loc <- etiqueta_unidad(unique(datos_01$unidad))

resultados_loc <- res01$resultados %>%
  mutate(etiqueta = factor(etiqueta_unidad(unidad), levels = orden_loc))

resultados_loc %>%
  transmute(`Tamaño de localidad` = etiqueta, Sexo = sexo,
            `C60 (%)` = 100 * C60, T0, T60, SMAM_hoja, SMAM_hajnal60) %>%
  mutate(across(where(is.numeric), ~ round(.x, 2))) %>%
  rmarkdown::paged_table()
ggplot(resultados_loc, aes(x = etiqueta, y = SMAM_hoja, color = sexo, group = sexo)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  scale_color_manual(values = colores_sexo) +
  labs(title = "SMAM por tamaño de localidad y sexo, Censo 2020",
       x = NULL, y = "SMAM (años)", color = "Sexo") +
  theme_minimal(base_size = 11) +
  theme(legend.position = "top",
        plot.title = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

5.8 Exportar los resultados

resultados_ent %>% select(-etiqueta) %>%
  write.csv("smam_censo2020_entidad_sexo.csv", row.names = FALSE, fileEncoding = "UTF-8")
detalle_ent %>% select(-etiqueta) %>%
  write.csv("smam_censo2020_bloque_hoja_SMAN.csv", row.names = FALSE, fileEncoding = "UTF-8")

Se generan dos archivos en la carpeta del .Rmd: los parámetros y SMAM por entidad y sexo, y el bloque A22:S37 completo de cada entidad y sexo.

Comparación con las notas de clase. Las notas reportan para México 2015 un SMAM de 30.65 años en hombres y 26.95 en mujeres (28.76 total). Esas cifras no son directamente comparables con las de 2020 de la hoja: cambian la fuente, el tratamiento de “No especificado” y la ventana de cálculo (15-50 en las notas, 12-60 en la hoja). Antes de interpretar un cambio entre 2015 y 2020 hay que confirmar que ambos usan la misma definición de soltero.


6 Tablas de nupcialidad: bruta y neta

Esta sección y la de estandarización amplían las notas de clase, que cubren hasta el SMAM.

La tabla de nupcialidad sigue a una cohorte de solteros desde los 15 años y registra su salida de la soltería, que puede ocurrir por dos causas competitivas: el primer matrimonio y la muerte antes de casarse. Es, por tanto, una tabla de decrementos múltiples.

6.1 Notación

  • \(l_x\): solteros que sobreviven en soltería a la edad exacta \(x\), con \(l_{15} = 100\,000\).
  • \(m_x\): tasa central de primer matrimonio entre solteros en \([x, x+n)\).
  • \(q^m_x\): probabilidad de casarse en el intervalo en ausencia de mortalidad.
  • \(q^d_x\): probabilidad de morir soltero en el intervalo en ausencia de matrimonio.
  • \(d^m_x\), \(d^d_x\): primeros matrimonios y defunciones de solteros observados en \([x, x+n)\).

6.2 Fórmulas

Conversión de la tasa a probabilidad, con distribución uniforme de eventos dentro del intervalo:

\[ q^m_x = \frac{_n\, m_x}{1 + \tfrac{n}{2}\, m_x} \]

Tabla neta (nupcialidad “pura”: se elimina la mortalidad, es decir, decremento simple por matrimonio):

\[ l^{\text{neta}}_{x+n} = l^{\text{neta}}_x\,(1 - q^m_x), \qquad d^{m,\text{neta}}_x = l^{\text{neta}}_x\, q^m_x \]

Tabla bruta (decremento doble, con mortalidad actuando en forma simultánea e independiente):

\[ d^m_x = l_x\, q^m_x \left(1 - \tfrac12 q^d_x\right), \qquad d^d_x = l_x\, q^d_x \left(1 - \tfrac12 q^m_x\right), \qquad l_{x+n} = l_x - d^m_x - d^d_x \]

Indicadores derivados (ambos con la tabla neta, truncados a los 50 años):

\[ \text{Prop. que se casa antes de 50} = 1 - \frac{l^{\text{neta}}_{50}}{l_{15}}, \qquad \bar{a}_{15\text{-}50} = \frac{\sum_x \left(x + \tfrac{n}{2}\right) d^{m,\text{neta}}_x}{\sum_x d^{m,\text{neta}}_x} \]

La terminología sigue la lógica de decrementos múltiples: neta es la probabilidad en ausencia de otras causas y bruta es la que ocurre en presencia de ellas. Las tasas \(m_x\) y \(q^d_x\) son ilustrativas, elegidas para tener el orden de magnitud de la nupcialidad femenina en México.

n      <- 5
edades <- seq(15, 45, by = n)   # inicio de cada intervalo
k      <- length(edades)

# Tasas de primer matrimonio entre solteros (inventadas)
m_x <- c(0.025, 0.085, 0.100, 0.090, 0.070, 0.045, 0.025)
# Probabilidad de morir soltero en el intervalo (inventadas)
q_d <- c(0.002, 0.003, 0.004, 0.005, 0.007, 0.010, 0.015)

# Tasa -> probabilidad (en ausencia de mortalidad)
q_m <- (n * m_x) / (1 + (n / 2) * m_x)

l0 <- 100000

## Tabla NETA: sólo matrimonio
l_neta   <- l0 * c(1, cumprod(1 - q_m))
dm_neta  <- l_neta[1:k] * q_m

## Tabla BRUTA: matrimonio y mortalidad compitiendo
l_bruta <- numeric(k + 1); l_bruta[1] <- l0
dm_b <- dd_b <- numeric(k)
for (i in seq_len(k)) {
  dm_b[i] <- l_bruta[i] * q_m[i] * (1 - q_d[i] / 2)
  dd_b[i] <- l_bruta[i] * q_d[i] * (1 - q_m[i] / 2)
  l_bruta[i + 1] <- l_bruta[i] - dm_b[i] - dd_b[i]
}

etiquetas <- paste0(edades, "-", edades + n - 1)

tabla_nupcialidad <- data.frame(
  Edad = etiquetas,
  q_m  = q_m, q_d = q_d,
  # Tabla bruta
  l_bruta = l_bruta[1:k], d_matrim = dm_b, d_defunc = dd_b,
  # Tabla neta
  l_neta = l_neta[1:k], d_matrim_neta = dm_neta
)

kable(tabla_nupcialidad, digits = c(0, 4, 4, 0, 0, 0, 0, 0),
      col.names = c("Edad", "q^m", "q^d", "l (bruta)", "d matrim.", "d defunc.",
                    "l (neta)", "d matrim. (neta)"),
      caption = "Tablas de nupcialidad simuladas (cohorte sintética de 100,000 solteros a los 15 años)")
Tablas de nupcialidad simuladas (cohorte sintética de 100,000 solteros a los 15 años)
Edad q^m q^d l (bruta) d matrim. d defunc. l (neta) d matrim. (neta)
15-19 0.1176 0.002 100000 11753 188 100000 11765
20-24 0.3505 0.003 88059 30820 218 88235 30928
25-29 0.4000 0.004 57021 22763 182 57307 22923
30-34 0.3673 0.005 34076 12486 139 34384 12631
35-39 0.2979 0.007 21450 6367 128 21753 6480
40-44 0.2022 0.010 14956 3010 134 15274 3089
45-49 0.1176 0.015 11811 1379 167 12185 1433
prop_casa_neta  <- 1 - l_neta[k + 1] / l0
edad_media_neta <- sum((edades + n / 2) * dm_neta) / sum(dm_neta)
prop_casa_bruta <- sum(dm_b) / l0
prop_muere      <- sum(dd_b) / l0

data.frame(
  Indicador = c("Se casa antes de los 50 (tabla neta)",
                "Se casa antes de los 50 (tabla bruta)",
                "Muere soltero antes de los 50 (tabla bruta)",
                "Edad media al primer matrimonio, 15-50 (tabla neta)"),
  Valor = c(sprintf("%.1f %%", 100 * prop_casa_neta),
            sprintf("%.1f %%", 100 * prop_casa_bruta),
            sprintf("%.1f %%", 100 * prop_muere),
            sprintf("%.1f años", edad_media_neta))
) %>% kable(caption = "Indicadores derivados de la tabla de nupcialidad")
Indicadores derivados de la tabla de nupcialidad
Indicador Valor
Se casa antes de los 50 (tabla neta) 89.2 %
Se casa antes de los 50 (tabla bruta) 88.6 %
Muere soltero antes de los 50 (tabla bruta) 1.2 %
Edad media al primer matrimonio, 15-50 (tabla neta) 26.7 años

La mortalidad antes del matrimonio reduce la proporción que llega a casarse de 89.2% (tabla neta) a 88.6% (tabla bruta). La diferencia es el costo en matrimonios de la mortalidad prematura de los solteros. Estos resultados son del mismo orden que el SMAM femenino nacional del Censo 2020 (24.8 años).


7 Estandarización por edad de las tasas de matrimonio (método directo)

Las tasas brutas de dos poblaciones no son comparables si difieren en estructura por edad. El método directo aplica las tasas específicas de cada población a una misma población estándar:

\[ \text{CMR}_{\text{est}} = \sum_{i} m_i \cdot c_i^{\text{std}}, \qquad c_i^{\text{std}} = \frac{P_i^{\text{std}}}{\sum_j P_j^{\text{std}}} \]

donde \(m_i\) es la tasa específica de matrimonio del grupo de edad \(i\) y \(c_i^{\text{std}}\) es la proporción de la población estándar en ese grupo. La tasa bruta, en cambio, pondera con la estructura propia de cada región:

\[ \text{CMR}_{\text{cruda}} = \sum_{i} m_i \cdot c_i^{\text{propia}} \]

La diferencia entre ambas diferencias, \(\Delta_{\text{cruda}} - \Delta_{\text{est}}\), cuantifica el efecto de composición por edad.

est <- data.frame(
  Grupo_Edad   = c("15-19", "20-24", "25-29", "30-34", "35-39", "40-49"),
  Pob_Estandar = c(25000, 22000, 20000, 18000, 15000, 20000),
  Pob_A        = c(30000, 28000, 24000, 18000, 12000, 18000),  # Región A (joven)
  Pob_B        = c(15000, 16000, 20000, 22000, 22000, 35000),  # Región B (envejecida)
  m_A          = c(0.012, 0.055, 0.070, 0.045, 0.025, 0.010),  # matrimonios por persona
  m_B          = c(0.005, 0.035, 0.065, 0.050, 0.030, 0.015)
)

est <- est %>%
  mutate(c_std = Pob_Estandar / sum(Pob_Estandar),
         c_A   = Pob_A / sum(Pob_A),
         c_B   = Pob_B / sum(Pob_B))

# Tasas brutas (por mil, restringidas a 15-49)
cmr_cruda_A <- sum(est$m_A * est$Pob_A) / sum(est$Pob_A) * 1000
cmr_cruda_B <- sum(est$m_B * est$Pob_B) / sum(est$Pob_B) * 1000

# Tasas estandarizadas (por mil)
cmr_est_A <- sum(est$m_A * est$c_std) * 1000
cmr_est_B <- sum(est$m_B * est$c_std) * 1000

dif_cruda <- cmr_cruda_A - cmr_cruda_B
dif_est   <- cmr_est_A   - cmr_est_B

kable(est %>% transmute(Grupo_Edad,
                        `% Estándar` = 100 * c_std,
                        `% Región A` = 100 * c_A,
                        `% Región B` = 100 * c_B),
      digits = 1, caption = "Estructura por edad (%) de la población estándar y de cada región")
Estructura por edad (%) de la población estándar y de cada región
Grupo_Edad % Estándar % Región A % Región B
15-19 20.8 23.1 11.5
20-24 18.3 21.5 12.3
25-29 16.7 18.5 15.4
30-34 15.0 13.8 16.9
35-39 12.5 9.2 16.9
40-49 16.7 13.8 26.9
res_est <- data.frame(
  Indicador = c("Tasa cruda (por mil)", "Tasa estandarizada (por mil)"),
  `Región A` = c(cmr_cruda_A, cmr_est_A),
  `Región B` = c(cmr_cruda_B, cmr_est_B),
  `Diferencia (A - B)` = c(dif_cruda, dif_est),
  check.names = FALSE
)
kable(res_est, digits = 2, caption = "Nupcialidad: tasas crudas vs. estandarizadas por edad")
Nupcialidad: tasas crudas vs. estandarizadas por edad
Indicador Región A Región B Diferencia (A - B)
Tasa cruda (por mil) 37.46 32.46 5.00
Tasa estandarizada (por mil) 35.79 32.04 3.75

La diferencia cruda entre regiones es de 5 por mil y la estandarizada de 3.75. Por tanto, aproximadamente 25% de la brecha bruta (crude) se debe a que la Región A es más joven y no a un comportamiento nupcial distinto.

Precaución. Las tasas específicas de A y B se cruzan (A es mayor a edades jóvenes, B a edades maduras). En ese caso el resultado estandarizado depende de la población estándar elegida. Conviene complementarlo con indicadores que no dependen de ella, como la tasa global de primeros matrimonios o el SMAM.


8 Conclusiones

  1. El SMAM estima la edad media a la primera unión sin necesidad de registros continuos de matrimonios. Basta una estructura por edad y estado civil de un censo o encuesta, aunque depende de la definición de “soltero” y de supuestos de estabilidad. Con el Censo 2020, la réplica de la hoja SMAN da un SMAM nacional de 27.5 años en hombres y 24.8 en mujeres. Por entidad, el SMAM masculino va de 25.9 a 30.7 años y el femenino de 23.1 a 28.2. Las tres observaciones sobre la hoja (rango de \(T_0\), unidades del denominador y ventana de suma) cambian el SMAM nacional hasta 1.1 años, por lo que conviene fijar cuál variante se reporta.
  2. La tabla de nupcialidad muestra la interacción entre la salida por matrimonio y la mortalidad prematura de los solteros. Distinguir la tabla neta (sin mortalidad) de la bruta (con mortalidad) evita atribuir a la nupcialidad lo que es efecto de la mortalidad.
  3. La estandarización directa separa el efecto de la estructura por edad del comportamiento nupcial. En el ejemplo, cerca de 25% de la diferencia cruda entre regiones es un efecto de composición.

9 Referencias

  • Hajnal, J. (1953). Age at marriage and proportions marrying. Population Studies, 7(2), 111-136.
  • Newell, C. (1988). Methods and Models in Demography. Belhaven Press.
  • Preston, S., Heuveline, P. y Guillot, M. (2001). Demography: Measuring and Modeling Population Processes. Blackwell.
  • Naciones Unidas (1983). Manual X: Técnicas indirectas de estimación demográfica.
  • INEGI (2021). Censo de Población y Vivienda 2020, tabulados del Cuestionario Básico: situación conyugal.
  • INEGI. Encuesta Intercensal 2015, tabulados de estado conyugal.