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.
¿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.
Sea \(M_t\) el número de matrimonios registrados en el año \(t\).
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 \]
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 \]
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)")| 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.
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:
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.
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} \]
| 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:
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.
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)
}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.
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).
## [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 federativarevisar <- 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")| 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 |
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:
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 \]
\[ Q_a = \frac{x^{*}_{\text{soltera},a}}{P_a}, \qquad _nL_x = n_a\, Q_a \]
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.
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:
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.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.\[ \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.
A22:W37) para cada entidad y sexoLas 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()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)")| 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 |
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).
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")| 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)")| sexo | Dif. media | Dif. mínima | Dif. máxima |
|---|---|---|---|
| Hombres | -0.35 | -0.55 | -0.16 |
| Mujeres | -0.77 | -1.15 | -0.43 |
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))
}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))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))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"))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))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.
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.
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)")| 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")| 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).
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")| 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")| 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.