1 Introducción


En este proyecto se va a realizar la metodología del Target trial. Dicha metodología consiste en realizar la emulación de un ensayo clínico a través de datos observacionales. En particular se aplica la metodología descrita en1. Empleando esta metodología, se van a emular múltiples ensayos con diferentes tiempos índice. Para cada tiempo índice se aplicaran los criterios de inclusión/exclusión del ensayo clínico a emular. Por lo tanto, vamos a tener individuos que pueden participar en más de un ensayo. En concreto, los no-iniciadores durante todo el periodo, y, los iniciadores, en el periodo previo a la iniciación, van a participar en más de una emulación del ensayo clínico siempre y cuando cumplan el resto de criterios de inclusión/exclusión.

El caso de estudio que se va a analizar es el de la efectivad vacunal de la tercera dosis (segunda para los pacientes de Janssen) en la población general de la comunidad foral de Navarra. En el conjunto de la población española, la efectividad estimada entre los días 7 hasta el 34 después de la tercera dosis, con fechas de vacunación comprendidas entre el 3 de enero y el 6 de febrero de 2022, fue del 51.3% (95% CI 50.2–52.4)2.


2 Exclusiones estáticas


En este .Rmd se realizan las exclusiones que no dependen del tiempo 0 y por tanto se realizan antes de determinar la fecha (fechas) de inicio de las emulaciones de los ensayos clínicos. Se alimenta a la función con una lista que contiene el texto del criterio de exclusión, para que se muestre por pantalla, y de las variables que definen dicho criterio. De momento, el tipo de variables que definen las exclusiones son de dos tipos:

  • Lógicas. Sí el valor es TRUE, es necesario excluir al individuo.

  • No lógicas. Se excluyen las variables de las cuales no se tiene información (en este caso se utiliza para eliminar las observaciones con NA en la zona básica de salud).

Cuando se genere nueva casuística, se puede añadir entre el if() y el else() de la función excluir().

# se crean listas que dependen del proyecto------------------------------------
lista_exclusion <- list(
  criterios = list(
  c1 = "Excluyendo: socio y/o sanitarios...",
  c2 = "Excluyendo: trabj educacion...", # no tengo claro que se hayan de excluir
  c3 = "Excluyendo: viven en residencia...",
  c4 = "Excluyendo: dependientes...",
  c5 = "Excluyendo: zona basica desconocida..."
  # c6 = "Excluyendo: tuvo infección previa...", # esta es dependiente del tiempo
  # c7 = "Excluyendo: no finalizo vacunacion completa 90 dias antes..." # dependiente del tiempo
),
variables = list(
  v1 = "prfss",
  v2 = "educa",
  v3 = "resn",
  v4 = "depe",
  v5 = "czbs"
))
# función para excluir siguiendo un criterio-----------------------------------
excluir <- function(pob, 
                    crit,
                    var)
{
  
  if (is.logical(pob %>% pull(var)) == TRUE) {
  print(glue("Variable lógica. {crit}"))
  pob <- pob %>% filter(is.na(get(var)) |
                     get(var) != TRUE)
    print(glue("n : {nrow(pob)}"))
  pob
  }
  else {
  print(glue("Variable no lógica. {crit}"))
  pob <- pob %>% filter(!is.na(get(var)))
    print(glue("n : {nrow(pob)}"))
  pob
  }
}
# flujo------------------------------------------------------------------------
hacer_flujo <- function(poblacion,
                        exc = lista_exclusion
                   ) 
  {
  print(glue("n de partida: {nrow(poblacion)}"))

  for(i in seq_along(exc$criterios)) {
  poblacion <- excluir(pob = poblacion,
                       crit = exc$criterios[[i]],
                       var = exc$variables[[i]])
}
  poblacion
  }
# aplicar exclusiones independientes del tiempo_0------------------------------
pobana_1 <- hacer_flujo(poblacion = pobana_0, 
            exc = lista_exclusion)
## n de partida: 488524
## Variable lógica. Excluyendo: socio y/o sanitarios...
## n : 468107
## Variable lógica. Excluyendo: trabj educacion...
## n : 394354
## Variable lógica. Excluyendo: viven en residencia...
## n : 385578
## Variable lógica. Excluyendo: dependientes...
## n : 379447
## Variable no lógica. Excluyendo: zona basica desconocida...
## n : 375735

3 Exclusiones dinámicas


En este .Rmd se realizan las exclusiones que sí dependen del tiempo 0 y por tanto se realizan en conjunción con la determinación del tiempo 0. De momento, el tipo de variables que definen las exclusiones son de dos tipos:

  • Variables de exclusión (NA se mantiene). Sí la fecha de la variable es menor a la del tiempo 0 se excluye al individuo. Si no hay fecha, se mantiene al individuo (p.e. fcv1 o fdef).

  • Variables inclusión (NA se excluye). Sí la fecha de la variable es mayor a la del tiempo 0 se excluye al individuo. Si no hay fecha, se excluye al individuo (p.e. fnac_40 o f_pauta_90).

Cuando se genere nueva casuística, se puede añadir entre el if() y el else() de la función excluir_dep().

# arreglar variables exclusión/inclusión dinámicas-----------------------------
pobana_2 <- pobana_1 %>% 
  # crear fecha 40 cumpleaños
  mutate(fnac_40 = fnac %m+% years(40)) %>% 
  # crear fecha 90 días tras pauta completa
  mutate(fpauta_90 = case_when(
    !is.na(fvc2) ~ fvc2 %m+% days(90),
    tvc1 == "J&J / Janssen" ~ fvc1 %m+% days(90),
    T ~ NA_Date_
    )) %>%
  mutate(tvc1_label = tvc1) %>% 
  # pautas de Janssen o de la misma vacuna
  filter(tvc1 == "J&J / Janssen" | tvc1 == tvc2)
# se crean listas que dependen del proyecto------------------------------------
lista_exclusion_dep <- list(
  criterios = list(
  c1 = "Excluyendo: infección previa antes del tiempo_0...",
  c2 = "Excluyendo: edad < 40 años en tiempo_0...", 
  c3 = "Excluyendo: pauta incompleta 90 días antes del tiempo_0...",
  c4 = "Excluyendo: fallecidos antes del tiempo_0...",
  c5 = "Excluyendo: boosting antes del tiempo_0..."),
  variables = list(
  v1 = "fcv1",
  v2 = "fnac_40",
  v3 = "fpauta_90",
  v4 = "fdef",
  v5 = "fvc3"),
  tipo_var = list(
    "exc",
    "inc",
    "inc",
    "exc",
    "exc")
  )
# aplicar exclusiones dependientes del tiempo_0------------------------------
pobana_2_2022_01_03 <- hacer_flujo_dep(
                                        data = pobana_2, 
                                        exc = lista_exclusion_dep,
                                        tiempo_0 = "2022-01-03"
                                        )
## n de partida: 374120
## Variable exclusión. Excluyendo: infección previa antes del tiempo_0...
## n : 330073
## Variable inclusión. Excluyendo: edad < 40 años en tiempo_0...
## n : 258322
## Variable inclusión. Excluyendo: pauta incompleta 90 días antes del tiempo_0...
## n : 256261
## Variable exclusión. Excluyendo: fallecidos antes del tiempo_0...
## n : 254713
## Variable exclusión. Excluyendo: boosting antes del tiempo_0...
## n : 105130

4 Target Trial (TT) emulation


# vectores de matching---------------------------------------------------------
variables_matching = c(
  "gen",    # 1
  "gedad",  # 2
  "czbs",   # 3
  "tvc1",   # 4
  "migran", # 5
  "vgp20",  # 6
  "vgp21",  # 7
  "ucn8",   # 8
  "domi")   # 9

4.1 TT con una fecha


# matching f_pauta en días
prueba_matching_days <- f_matching_tt(
                data = pobana_2,
                tiempo_0 = "2022-01-03",
                crit_exc = lista_exclusion_dep,
                exposure = "fvc3",
                out = "fcv1", 
                vector_match = variables_matching[c(1, 3:8)],
                match_with_replacement = TRUE,
                dias_a_excluir_test_previos = NULL,
                base_test = test220613_cleaned,
                temporal_var = "fpauta_90",
                temporal_var_unit = "days",
                birth_date = "fnac",
                age_first = 40,
                age_last = 90,
                age_by = 5,
                censoring = "fdef",
                delayed_exposure_censoring = NULL,
                follow_up = 34,
                verbose = FALSE,
                seed = 3)
## tiempo_0 = 2022-01-03

4.2 TT con más de una fecha

# matching f_pauta en días (menos restrictivo)
prueba_matching_mult_days <- f_matching_tt_mult(
                data = pobana_2,
                f_ini = "2022-01-03",
                f_fin = "2022-01-05",
                crit_exc = lista_exclusion_dep,
                exposure = "fvc3",
                out = "fcv1", 
                vector_match = variables_matching[c(1, 3:8)], 
                base_test = test220613_cleaned,
                temporal_var = "fpauta_90",
                temporal_var_unit = "days",
                birth_date = "fnac",
                age_first = 40,
                age_last = 90,
                age_by = 5,
                censoring = "fdef",
                follow_up = 34,
                verbose = FALSE,
                seed = 3)
## tiempo_0 = 2022-01-03
## tiempo_0 = 2022-01-04
## tiempo_0 = 2022-01-05

5 Análisis


# análisis con variables de matching como el artículo--------------------------
f_analisis(lista = prueba_matching_mult_days,
           tiempo_efecto = 7,
           lim_1 = 0.8,
           lim_zoom = 0.9)
## Se está analizando el outcome: fcv1 mediante la emulación de un ensayo clínico  con múltiples inicios de tiempo. Se ha utilizado matching por: gen, czbs, tvc1, migran, vgp20, vgp21, ucn8, n_0, fpauta_90 (in days), age (in 5-years groups).
## 
## Análisis de supervivencia días 0-34
##             caso          
##  exposicion    0   1 Total
##           0 1130  86  1216
##           1 1170  46  1216
##       Total 2300 132  2432
##   
## # Estimated effectiveness in Navarra for fcv1 is : 49.1 % (27.2 - 64.4 %)
## Warning: Removed 14 row(s) containing missing values (geom_path).
## Warning: Removed 14 rows containing missing values (geom_point).
## Warning: Removed 14 row(s) containing missing values (geom_path).
## Warning: Removed 14 rows containing missing values (geom_point).

## 
##  ########################################################################
## 
## Análisis de supervivencia días 7-34
##             caso         
##  exposicion    0  1 Total
##           0  778 29   807
##           1  792 15   807
##       Total 1570 44  1614
##   
## # Estimated effectiveness in Navarra for fcv1 is : 49.7 % (6.2 - 73 %)

6 Hacer tabla 1


# ejecutar la función para hacer la tabla--------------------------------------
tabla_1_demo <- hacer_tabla_1(tt_tibble = prueba_matching_mult_days$tt_tibble)

tabla_1_demo
Table 6.1: Baseline characteristics of the matched study population
Variable No booster group (n = 1216*) Booster group (n = 1216)
Age group (years), n (%)
40-44 5 (0.4%) 5 (0.4%)
45-49 23 (1.9%) 23 (1.9%)
50-54 593 (48.8%) 593 (48.8%)
55-59 571 (47.0%) 571 (47.0%)
60-64 11 (0.9%) 11 (0.9%)
65-69 2 (0.2%) 2 (0.2%)
70-74 6 (0.5%) 6 (0.5%)
75-79 1 (0.1%) 1 (0.1%)
80-84 0 (0.0%) 0 (0.0%)
85-89 4 (0.3%) 4 (0.3%)
≥ 90 0 (0.0%) 0 (0.0%)
Sex, n (%)
Men 773 (63.6%) 773 (63.6%)
Women 443 (36.4%) 443 (36.4%)
Number of previous SARS-CoV-2 tests, n (%)
0 735 (60.4%) 735 (60.4%)
1 231 (19.0%) 231 (19.0%)
2 142 (11.7%) 142 (11.7%)
≥ 3 108 (8.9%) 108 (8.9%)
Type of previous vaccination, n (%)
BioNTech/Pfizer 848 (69.7%) 848 (69.7%)
J&J / Janssen 3 (0.2%) 3 (0.2%)
Moderna/Lonza 350 (28.8%) 350 (28.8%)
Oxford/AstraZeneca 15 (1.2%) 15 (1.2%)
Time since primary vaccine schedule, n (%)
91-150 days 0 (0.0%) 0 (0.0%)
151-180 days 15 (1.2%) 15 (1.2%)
≥ 181 days 1201 (98.8%) 1201 (98.8%)
Type of booster, n (%)
BioNTech/Pfizer NA 61 (5.0%)
Moderna/Lonza NA 1155 (95.0%)
Note: NA = not applicable, *1172 unique individuals in the no booster group.

7 Hacer tabla 2


tabla_2_demo
Table 7.1: Estimated effectiveness of an mRNA COVID-19 vaccine booster in individuals* who had completed primary vaccination schedule against COVID-19
No booster group
Booster group
1–risk ratio (95% CI)
Risk difference per 10 000 individuals (95% CI)
Events Risk per 10 000 individuals Events Risk per 10 000 individuals
Overall 29 621 15 296 52.3 % (-1.3, 79.1) 325 (-6, 646)
Age group (years)
40-54 15 671 10 456 32.1 % (-60.1, 76.2) 215 (-229, 641)
≥ 55 14 578 5 135 76.6 % (39.3, 95.2) 443 (142, 806)
Sex
Male 16 493 8 266 45.9 % (-54.8, 83.2) 226 (-156, 580)
Female 13 795 7 339 57.3 % (-2.3, 89.3) 456 (-8, 954)
Type of previous vaccination
BioNTech/Pfizer 18 576 9 291 49.4 % (-16.7, 83.9) 285 (-62, 621)
J&J / Janssen 0 0 0 0 NaN % (NA, NA) 0 (0, 0)
Moderna/Lonza 11 746 6 310 58.5 % (-34.8, 89.3) 436 (-90, 919)
Oxford/AstraZeneca 0 0 0 0 NaN % (NA, NA) 0 (0, 0)
Time since vaccination completed
91-195 days 12 793 5 356 55.1 % (-28.2, 91.2) 437 (-111, 1072)
196-220 days 16 533 10 287 46.3 % (-29.7, 80.6) 247 (-108, 582)
≥ 221 days 1 833 0 0 100 % (100, 100) 833 (0, 2857)
Type of booster
BioNTech/Pfizer 1 526 1 769 -46.2 % (-Inf, 100) -243 (-2143, 1429)
Moderna/Lonza 28 623 14 263 57.9 % (17.9, 81.6) 361 (74, 655)
Note: Analyses based on 807 matched pairs who remained under follow-up by day 7 after the booster dose

8 Referencias


1
2
Monge S, Rojas-Benedicto A, Olmedo C, et al. Effectiveness of mRNA vaccine boosters against infection with the SARS-CoV-2 omicron (B.1.1.529) variant in Spain: a nationwide cohort study. The Lancet Infectious Diseases 2022; published online June. DOI:10.1016/S1473-3099(22)00292-4.