6.10 Vinculación de registros

Con el fin de integrar la información proveniente de la muestra E y la muestra P, se debe llevar a cabo un proceso de emparejamiento de registros. Este procedimiento es fundamental para identificar unidades observadas en ambas muestras y, de esta manera implementar el modelo basado en el sistema de estimación dual.

El proceso de vinculación de registros entre la muestra E y la muestra P se fundamenta en la comparación de variables clave que están presentes en ambas bases de datos. Entre estas variables se incluyen información como nombres, apellidos, sexo y fecha de nacimiento, las cuales permiten establecer la correspondencia entre los individuos de cada muestra. Estas coincidencias constituyen la base para identificar si un mismo registro aparece en las dos fuentes de información.

La forma de implementar este procedimiento es análoga al utilizado previamente para la detección de duplicados dentro de una misma base de datos. La diferencia principal radica en los conjuntos de datos que se introducen en los argumentos de la función de emparejamiento: en lugar de comparar una base consigo misma, en este caso se contrasta la muestra E frente a la muestra P. De esta manera, se logra identificar registros compartidos entre las dos muestras, manteniendo la misma lógica de comparación, pero adaptada a un contexto de integración de fuentes.

En el caso del paquete RecordLinkage, se cuenta con dos funciones para la creación de patrones de comparación a partir de conjuntos de datos: compare.dedup() o RLBigDataDedup(), para la deduplicación de un único conjunto de datos como se presentó en la sección anterior, y compare.linkage() o RLBigDataLinkage(), para vincular dos conjuntos de datos diferentes, la diferencia es que la segunda función está diseñada para grandes conjuntos de datos.

Considere los conjuntos de datos de la muestra E y de la muestra P, almacenados previamente en los objetos censo_limpio y encuesta_limpia. Ahora se creará la variable de fecha con el valor de la fecha de nacimiento.

library(pacman)
p_load(tidyverse, RecordLinkage, lubridate)

df_censo <- censo_limpio |> 
  mutate(fecha_nacimiento = make_date(year = anio_nac, month = mes_nac, day = dia_nac)) |> 
    select(id_segmento, ends_with("cod"), sexo, fecha_nacimiento)

df_encuesta <- encuesta_limpia |> 
    mutate(fecha_nacimiento = make_date(year = anio_nac, month = mes_nac, day = dia_nac)) |> 
    select(id_segmento, ends_with("cod"), sexo, fecha_nacimiento)

Para el ejemplo se usará el paquete RecordLinkage. En este caso la muestra P contiene 54 registros y la muestra E contiene 97 registros, en este caso se aplicará una indexación usando como bloques el id_segmento. La estructura de la base de la muestra E es la siguiente

head(df_censo)
## # A tibble: 6 × 5
##   id_segmento nombre_cod apellido_cod sexo  fecha_nacimiento
##         <int> <chr>      <chr>        <chr> <date>          
## 1         101 KRLS       PRS          m     1947-01-01      
## 2         101 LK         KSTR         f     1975-01-01      
## 3         101 KML        KSTR         f     2012-01-01      
## 4         101 MR         KSTR         f     1959-01-01      
## 5         102 YRG        GMS          m     1954-01-01      
## 6         102 SF         RMRS         f     2000-01-01

Mientras que la muestra P es la siguiente, es de recordar que los conjuntos de datos ya fueron sometidos a un preprocesamiento, y note que los conjuntos de datos se han alineado para que las variables se denominen de la misma forma:

head(df_encuesta)
## # A tibble: 6 × 5
##   id_segmento nombre_cod apellido_cod sexo  fecha_nacimiento
##         <int> <chr>      <chr>        <chr> <date>          
## 1         101 MR         KSTR         f     1959-01-01      
## 2         101 KRLS       PRS          m     1947-01-01      
## 3         101 LK         KSTR         f     1975-01-01      
## 4         101 KML        RMRS         f     2010-01-01      
## 5         101 SF         KSTR         f     1966-01-01      
## 6         101 N          MRTNS        f     1973-01-01

La función compare.linkage() construye los patrones para la vinculación de los registros, en este caso se compara la muestra E y la muestra P usando como bloque el segmento.

empareja <- compare.linkage(dataset1 = df_encuesta,
                            dataset2 = df_censo,
                            blockfld = 1, #Bloque por id_segmento
                            strcmp = c("nombre_cod", "apellido_cod", "sexo"),
                            exclude = "id_segmento"
                            )

Una vez realizadas las comparaciones utilizando los criterios especificados, se aplica el algoritmo para calcular la probabilidad de coincidencia. Para ello, el paquete RecordLinkage cuenta con los algoritmos de Fellegi-Sunter, EpiLink y EM.

empareja_fs <- RecordLinkage::fsWeights(empareja)
#empareja_em <- RecordLinkage::emWeights(empareja)
#empareja_ep <- RecordLinkage::epiWeights(empareja)
summary(empareja_fs)
## 
## Linkage Data Set
## 
## 54 records in data set 1 
## 97 records in data set 2 
## 1750 record pairs 
## 
## 0 matches
## 0 non-matches
## 1750 pairs with unknown status
## 
## 
## Weight distribution:
## 
## [-16,-14] (-14,-12] (-12,-10]  (-10,-8]   (-8,-6]   (-6,-4]   (-4,-2]    (-2,0] 
##       743         0       601       114         0       217         0         1 
##     (0,2]     (2,4]     (4,6]     (6,8]    (8,10]   (10,12]   (12,14] 
##         0        18         2         0         1         0        53

El análisis de la distribución de los pesos muestra que, aunque la mayoría de los pares se concentran en valores negativos, lo que indica una baja similitud y, por tanto, una baja probabilidad de coincidencia. Hay algunos pares que alcanzan valores positivos, y dentro de estos, se observa que algunos se ubican en el rango más alto, por lo que tienen una alta probabilidad de ser emparejamientos verdaderos.

Cuando los conjuntos de datos son muy grandes, se puede usar un enfoque basado en la función RLBigDataLinkage en vez de compare.linkage, solo debe tener en cuenta que al ser objetos S4 debe ver los resultados usando el simbolo @, por ejemplo summary(empareja_fs@Wdata).

Los algoritmos calculan la probabilidad de coincidencia para cada registro en df_encuesta con cada registro en el conjunto de df_censo cuando pertenecen al mismo segmento, basándose en los patrones de comparación especificados. Ahora, es necesario realizar la clasificación como emparejado, emparejamiento potencial o no emparejado. Para hacer esta clasificación, es necesario establecer el umbral de clasificación.

La elección del umbral suele ser un aspecto relevante. Si es muy bajo, se podría estar aceptando demasiados falsos positivos; si es muy alto, se podría perder verdaderos emparejados. una de las herramientas del paquete RecordLinkage es la función getParetoThreshold(), que puede ser útil para identificar el umbral de aceptación. Sin embargo, con conjuntos de datos grandes podría tardar mucho en ejecutarse.

La siguiente gráfica es interactiva y permite observar cómo cambia la vida residual media a medida que sube el umbral. Se ha comentado la línea debido a que no puede compilarse por bookdown, y se ha tomado el umbral automático. La idea básica es identificar el punto de cambio de la pendiente en la curva, para ello puede usar un criterio como el del codo.

#Este es un diagrama interactivo, por lo que se comenta la línea 
#umbral <- getParetoThreshold(empareja_fs) 
umbral <- 5.86

Una vez definido el umbral, se puede extraer en un conjunto de datos a los registros clasificados como emparejados. La primera fila corresponde al registro en df_encuesta mientras que el segundo corresponde al registro en df_censo.

emparejado <- getPairs(empareja_fs, min.weight = umbral)
Registros emparejados
id id_segmento nombre_cod apellido_cod sexo fecha_nacimiento Weight
1 101 MR KSTR f 1959-01-01
4 101 MR KSTR f 1959-01-01 13.278591201562502
2 101 KRLS PRS m 1947-01-01
1 101 KRLS PRS m 1947-01-01 13.278591201562502
3 101 LK KSTR f 1975-01-01
2 101 LK KSTR f 1975-01-01 13.278591201562502
4 101 KML RMRS f 2010-01-01
87 101 KML RMRS f 2010-01-01 13.278591201562502
5 101 SF KSTR f 1966-01-01
9 101 SF KSTR f 1966-01-01 13.278591201562502
6 101 N MRTNS f 1973-01-01
12 101 N MRTNS f 1973-01-01 13.278591201562502
7 101 LK MRN f 2003-01-01
21 101 LK MRN f 2003-01-01 13.278591201562502
8 101 YRG MRN m 1955-01-01
19 101 YRG MRN m 1955-01-01 13.278591201562502
9 101 NDRS KSTR m 1936-01-01
28 101 NDRS KSTR m 1936-01-01 13.278591201562502
10 101 N TRS f 2017-01-01
29 101 N TRS f 2017-01-01 13.278591201562502
11 101 N MRTNS f 2001-01-01
42 101 N MRTNS f 2001-01-01 13.278591201562502
12 101 YN KSTR m 2015-01-01
41 101 YN KSTR m 2015-01-01 13.278591201562502
13 101 PDR LPS m 2001-01-01
50 101 PDR LPS m 2001-01-01 13.278591201562502
14 101 PDR RMRS m 2018-01-01
51 101 PDR RMRS m 2018-01-01 13.278591201562502
15 101 YRG KSTR m 1946-01-01
59 101 YRG KSTR m 1946-01-01 13.278591201562502
16 101 YRG KSTR m 1988-01-01
57 101 YRG KSTR m 1988-01-01 13.278591201562502
17 101 SF GMS f 2007-01-01
70 101 SF GMS f 2007-01-01 13.278591201562502
18 101 YRG TRS m 1969-01-01
79 101 YRG TRS m 1969-01-01 13.278591201562502
19 102 YRG GMS m 1954-01-01
5 102 YRG GMS m 1954-01-01 13.278591201562502
20 102 N RMRS f 1963-01-01
92 102 N RMRS f 1963-01-01 13.278591201562502
21 102 N GRK f 1985-01-01
13 102 N GRK f 1985-01-01 13.278591201562502
22 102 KRLS RMRS m 1942-01-01
23 102 KRLS RMRS m 1942-01-01 13.278591201562502
23 102 YN KSTR m 2006-01-01
32 102 YN KSTR m 2006-01-01 13.278591201562502
24 102 PDR MRN m 1990-01-01
34 102 PDR MRN m 1990-01-01 13.278591201562502
25 102 MR LPS f 1935-01-01
45 102 MR LPS f 1935-01-01 13.278591201562502
26 102 NDRS GRK m 2020-01-01
44 102 NDRS GRK m 2020-01-01 13.278591201562502
27 102 PDR RDRGS m 2025-01-01
46 102 PDR RDRGS m 2025-01-01 13.278591201562502
28 102 YN GRK m 2009-01-01
53 102 YN GRK m 2009-01-01 13.278591201562502
29 102 YRG LPS m 1987-01-01
64 102 YRG LPS m 1987-01-01 13.278591201562502
30 102 KRLS RDRGS m 1985-01-01
62 102 KRLS RDRGS m 1985-01-01 13.278591201562502
31 102 PDR GMS m 1983-01-01
63 102 PDR GMS m 1983-01-01 13.278591201562502
32 102 KML TRS f 1973-01-01
71 102 KML TRS f 1973-01-01 13.278591201562502
33 102 YRG TRS m 1976-01-01
74 102 YRG TRS m 1976-01-01 13.278591201562502
34 102 N MRN f 1998-01-01
72 102 N MRN f 1998-01-01 13.278591201562502
35 102 N GRK f 1990-01-01
83 102 N GRK f 1990-01-01 13.278591201562502
36 102 LK PRS f 2020-01-01
82 102 LK PRS f 2020-01-01 13.278591201562502
38 103 KRLS MRN m 1950-01-01
7 103 KRLS MRN m 1950-01-01 13.278591201562502
39 103 YN PRS m 1945-01-01
96 103 YN PRS m 1945-01-01 13.278591201562502
40 103 KML KSTR f 1974-01-01
17 103 KML KSTR f 1974-01-01 13.278591201562502
41 103 MR PRS f 1994-01-01
25 103 MR PRS f 1994-01-01 13.278591201562502
42 103 PDR MRN m 1939-01-01
38 103 PDR MRN m 1939-01-01 13.278591201562502
43 103 NDRS PRS m 2010-01-01
37 103 NDRS PRS m 2010-01-01 13.278591201562502
44 103 PDR GMS m 2009-01-01
48 103 PDR GMS m 2009-01-01 13.278591201562502
45 103 SF MRTNS f 1962-01-01
49 103 SF MRTNS f 1962-01-01 13.278591201562502
46 103 KRLS MRN m 1995-01-01
47 103 KRLS MRN m 1995-01-01 13.278591201562502
47 103 PDR KSTR m 2009-01-01
54 103 PDR KSTR m 2009-01-01 13.278591201562502
48 103 PDR MRN m 2024-01-01
55 103 PDR MRN m 2024-01-01 13.278591201562502
49 103 YN LPS m 1977-01-01
56 103 YN LPS m 1977-01-01 13.278591201562502
50 103 N PRS f 2000-01-01
67 103 N PRS f 2000-01-01 13.278591201562502
51 103 LK MRN f 1967-01-01
78 103 LK MRN f 1967-01-01 13.278591201562502
52 103 MR LPS f 1945-01-01
76 103 MR LPS f 1945-01-01 13.278591201562502
53 103 N MRTNS f 2001-01-01
84 103 N MRTNS f 2001-01-01 13.278591201562502
54 103 NDRS LPS m 2022-01-01
85 103 NDRS LPS m 2022-01-01 13.278591201562502
37 102 NDRS LPS f 1986-01-01
81 102 NDRS LPS m 1986-01-01 9.030663688118919
44 103 PDR GMS m 2009-01-01
54 103 PDR KSTR m 2009-01-01 5.860738686676607
47 103 PDR KSTR m 2009-01-01
48 103 PDR GMS m 2009-01-01 5.860738686676607

De igual forma, usando la misma gráfica obtenida con getParetoThreshold() se puede establecer un umbral más flexible, y encontrar los emparejamientos potenciales. En nuestro ejemplo se tomarán como aquellos registros que tienen un ponderador entre 1.2 y el umbral, los cuales pasarán a una revisión clerical para establecer si se clasifican como emparejados o no emparejados

posibles <- getPairs(empareja_fs, min.weight = 1.2, max.weight = umbral)
posibles %>%
  gt() %>%
  tab_header(
    title = "Emparejamientos potenciales"
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "#f9f9f9"),
      cell_text(weight = "bold")
    ),
    locations = cells_column_labels()
  ) %>%
  tab_options(
    table.width = pct(100),
    container.height = px(400) 
  )
Emparejamientos potenciales
id id_segmento nombre_cod apellido_cod sexo fecha_nacimiento Weight
6 101 N MRTNS f 1973-01-01
42 101 N MRTNS f 2001-01-01 3.123773092510401
9 101 NDRS KSTR m 1936-01-01
40 101 NDRS KSTR m 1949-01-01 3.123773092510401
11 101 N MRTNS f 2001-01-01
12 101 N MRTNS f 1973-01-01 3.123773092510401
12 101 YN KSTR m 2015-01-01
10 101 YN KSTR m 1973-01-01 3.123773092510401
13 101 PDR LPS m 2001-01-01
11 101 PDR LPS m 2019-01-01 3.123773092510401
14 101 PDR RMRS m 2018-01-01
58 101 PDR RMRS m 1962-01-01 3.123773092510401
15 101 YRG KSTR m 1946-01-01
57 101 YRG KSTR m 1988-01-01 3.123773092510401
16 101 YRG KSTR m 1988-01-01
59 101 YRG KSTR m 1946-01-01 3.123773092510401
21 102 N GRK f 1985-01-01
83 102 N GRK f 1990-01-01 3.123773092510401
23 102 YN KSTR m 2006-01-01
43 102 YN KSTR m 2012-01-01 3.123773092510401
35 102 N GRK f 1990-01-01
13 102 N GRK f 1985-01-01 3.123773092510401
36 102 LK PRS f 2020-01-01
16 102 LK PRS f 1966-01-01 3.123773092510401
38 103 KRLS MRN m 1950-01-01
47 103 KRLS MRN m 1995-01-01 3.123773092510401
40 103 KML KSTR f 1974-01-01
26 103 KML KSTR f 2019-01-01 3.123773092510401
42 103 PDR MRN m 1939-01-01
55 103 PDR MRN m 2024-01-01 3.123773092510401
43 103 NDRS PRS m 2010-01-01
18 103 NDRS PRS m 2004-01-01 3.123773092510401
46 103 KRLS MRN m 1995-01-01
7 103 KRLS MRN m 1950-01-01 3.123773092510401
48 103 PDR MRN m 2024-01-01
38 103 PDR MRN m 1939-01-01 3.123773092510401

Finalizado el proceso, los registros que se lograron emparejar deben ser retirados del conjunto de datos df_encuesta y el conjunto df_censo debe ampliarse con otros segmentos aledaños a la muestra E, para repetir el proceso.