Introducción


En este documento se muestra la utilización de un diseño de Análisis caso control negativo en el tiempo desde prueba diagnóstica (test negative case control). En particular, se realiza la emulación del ensayo clínico partiendo del caso (individuo con test positivo) y emparejando con un control que se haya realizado una prueba diagnóstica ese mismo día (individuo con test negativo).

Para comprobar el funcionamiento del diseño tncc se realizan tres análisis:

  1. Un análisis donde se estudia a la población general sin aplicar criterios de exclusión dependientes del tiempo (los criterios de exclusión independientes del tiempo sí que se han aplicado: no trabajadores sanitarios ni de educación, no residentes, etc.).

  2. Se excluyen a los individuos que no tengan la pauta primaria de vacunación (2 dosis de Pfizer, AZ y Moderna, o al menos 1 dosis de Janssen) con una antigüedad de 90 o más días en el tiempo_0.

  3. Se excluyen a los individuos que no tengan la pauta primaria de vacunación (2 dosis de Pfizer, AZ y Moderna, o al menos 1 dosis de Janssen) con una antigüedad de 90 o más días en el tiempo_0, y, además, se excluyena los individuos que hayan tenido infección por COVID-19 previa al tiempo_0.

Para los tres análisis:

  • Se estudia el periodo: 2022-01-03 a 2022-06-13.

  • Se empareja por: sexo, migrante y grupos de edad (5 años).

Por último, se realiza un último análisis:

  1. Análisis similar al 3, pero con el periodo: 2022-01-10 a 2022-03-10 y emparejando por: sexo, migrante, grupos de edad (5 años), tipo de vacuna en la vacunación primaria, zona básica, vacuna de la gripe (2020), vacuna de la gripe (2021) y número de convivientes (truncado en 8).

Análisis 1


Se estudia a la población general filtrada por criterios de exclusión independientes del tiempo (Pobana_2: población sin criterios de exclusión dependientes del tiempo). En esta población, existen 6 categorías posibles de tratamiento, del mismo modo que en1:

  1. Sin pauta de vacunación previa completa (sin booster), y sin registro de COVID-19 previa.
  2. Sin pauta de vacunación previa completa (sin booster), y con registro de COVID-19 previa.
  3. Con pauta de vacunación previa completa, sin booster, y sin registro de COVID-19 previa.
  4. Con pauta de vacunación previa completa, sin booster, y con registro de COVID-19 previa.
  5. Con pauta de vacunación previa completa, con booster, y sin registro de COVID-19 previa.
  6. Con pauta de vacunación previa completa, con booster, y con registro de COVID-19 previa.

En la Figura 1 se muestra el resultado de la efectividad estimada de los distintos tratamientos posibles del análisis.


Resultados del Análisis 1

Figure 1: Resultados del Análisis 1


Análisis 2


Se estudia a mayores de 40 con pauta previa completa. Por lo tanto, van a existir 4 categorías posibles de tratamiento:

  1. Sin booster y sin registro de COVID-19 previa.
  2. Sin booster y con registro de COVID-19 previa.
  3. Con booster y sin registro de COVID-19 previa.
  4. Con booster y con registro de COVID-19 previa.

En la Figura 3 se muestra el resultado de la efectividad estimada de los distintos tratamientos posibles del análisis.


Resultados del Análisis 2

Figure 2: Resultados del Análisis 2


Análisis 3


Se estudia a los mayores de 40, con pauta previa y sin COVID previa. Por lo tanto, únicamente se tienen 2 categorías de tratamiento:

  1. Sin booster.
  2. Con booster.

En la Figura 3 se muestra el resultado de la efectividad estimada del Booster frente a No-Booster.


Resultados del Análisis 3

Figure 3: Resultados del Análisis 3


Análisis 4


Se estudia a los mayores de 40, con pauta previa y sin COVID previa. Por lo tanto, únicamente se tienen 2 categorías de tratamiento:

  1. Sin booster.
  2. Con booster.

En la Figura 4 se muestra el resultado de la efectividad estimada del Booster frente a No-Booster.


Resultados del Análisis 4

Figure 4: Resultados del Análisis 4


El resultado es todavía más similar al que se obtenía con el target trial prospectivo. El inconveniente es que al reducir el periodo de estudio y al exigir emparejar por más variables (además del emparejamiento por el test), el tamaño de la muestra se reduce de n = 101 018 del Análisis 3 a n = 2030 del Análisis 4.


La función


f_matching_tncc

En esta función se realiza un diseño de caso-control negativo desde la realización de un test (positivo = caso / negativo = control).

# función de matching tncc
f_matching_tncc <- function(
                          data, 
                          tiempo_0,
                          caso_control_var,
                          caso_control_date,
                          vector_match,
                          crit_exc = NULL,
                          match_with_replacement = TRUE,
                          base_test = NULL,
                          dias_a_excluir_test_previos = NULL,
                          temporal_var = NULL,
                          temporal_var_unit = "days",
                          birth_date = NULL,
                          age_first = NULL,
                          age_last = NULL,
                          age_by = NULL,
                          verbose = TRUE,
                          seed = 1) {
  
  set.seed(seed)
  tiempo_0 <- ymd(tiempo_0)
  print(glue("tiempo_0 = {tiempo_0}"))
  # exclusiones dependientes del tiempo
  if (!missing(crit_exc)){
  for(i in seq_along(crit_exc$criterios)) {
  data <- excluir_dep(
                       pob = data,
                       crit = crit_exc$criterios[[i]],
                       var = crit_exc$variables[[i]],
                       t_var = crit_exc$tipo_var[[i]],
                       t0 = tiempo_0,
                       vb = verbose)
  } 
    }
  
    data <- data %>%
    # exclusión covid positivo en los 90 días previos al test
    filter(
      is.na(fcv1) |
      as.numeric(tiempo_0 - fcv1) >= 90 | 
      as.numeric(tiempo_0 - fcv1) <= 0,
      is.na(fcv2) |
      as.numeric(tiempo_0 - fcv2) >= 90 | 
      as.numeric(tiempo_0 - fcv2) <= 0) %>% 
    # obtención variable de covid previo
    mutate(fcv1_prev = if_else((as.numeric(tiempo_0 - fcv1) >= 90) == TRUE,
                               fcv1, NA_Date_))
  
    data <- base_test %>% filter(id %in% data$id,
                               get(caso_control_date) == tiempo_0) %>%
     inner_join(data, by = "id")
  
  # introducir edad como variable de matching respecto a tiempo_0
  if (!missing(birth_date)) {
    if(is.null(age_first) || is.null(age_last) || is.null(age_by)) {
      stop(strwrap(prefix = " ", initial = "", 
           "Have you introduced 'age_first', 'age_last',
           and, 'age_by' arguments properly?"))
    }
    data <- data %>% 
      mutate(p_edad_cat = cut(as.numeric(difftime(tiempo_0, get(birth_date), 
                                              unit = "days"))/365.25,
                          right = FALSE, 
                          breaks = c(0,
                                     seq(age_first, age_last,
                                         by = age_by),
                                     200))) %>% 
    mutate(p_edad_cat_label = p_edad_cat)
  # actualizar variables matching  
  vector_match <- c(vector_match, "p_edad_cat")
  }
  
  # exposicion-seguimiento
  data <- data %>%
    mutate(across(.cols = all_of(vector_match), 
                  .fns = ~if_else(is.na(as.numeric(.x)) == TRUE, 
                                  as.numeric(as.factor(.x)),
                                  as.numeric(.x))))  %>%     
    mutate(caso_control = if_else(get(caso_control_var) == TRUE, 1, 0),
           date_start = tiempo_0)
    
  # hacer matching (investigar distintas opciones)
  try({
    greedymatch <- Matching::Match(Tr = data$caso_control, M = 1, 
                   X = data[vector_match], exact = TRUE, ties = FALSE,
                   replace = match_with_replacement)
    a <- data[unlist(greedymatch[c("index.treated", "index.control")]),]
    par <- rep(1:(nrow(a)/2), 2)
    bind_cols(par = par, a) %>%
      group_by(par) %>% 
      as_tibble() 
    }
  )
}

f_matching_tncc_mult

Extensión de la función f_matching_tncc, en la cuál se obtiene un ensayo clínico emulado para cada tiempo_0 y se unen en un único tibble.

# función de matching para múltiples fechas------------------------------------
f_matching_tncc_mult <- function(
                             data, 
                             f_ini,
                             f_fin,
                             caso_control_var,
                             caso_control_date,
                             vector_match,
                             crit_exc = NULL,
                             match_with_replacement = TRUE,
                             base_test = NULL,
                             dias_a_excluir_test_previos = NULL,
                             temporal_var = NULL,
                             temporal_var_unit = "days",
                             birth_date = NULL,
                             age_first = NULL,
                             age_last = NULL,
                             age_by = NULL,
                             verbose = TRUE,
                             seed = 1){
  
  fechas <- seq.Date(from = ymd(f_ini), to = ymd(f_fin), by = "days")
  
  tt_tibble =  map(fechas, 
      f_matching_tncc,
      data = data,
      crit_exc = crit_exc,
      caso_control_var = caso_control_var,
      caso_control_date = caso_control_date,
      vector_match = vector_match,
      match_with_replacement = match_with_replacement,
      base_test = base_test,
      birth_date = birth_date,
      age_first = age_first,
      age_last = age_last,
      age_by = age_by,
      verbose = verbose,
      seed = seed) %>% 
    # descartar los días en los que no se encuentra matching
    keep(~is_tibble(.x)) %>%  
    # unir todos los tibbles de la lista en uno único
    enframe() %>%
    rename(target_trial_number = name) %>% 
    unnest(value) 
    # para evitar errores en el matcheo
    # filter(!is.na(caso_control))    # filter(!is.na(caso_control))

  if (!missing(birth_date)) {
  vector_match  <- c(vector_match, 
                     glue("age (in {age_by}-years groups)"))
  }  
  
  return(lst(tt_tibble = tt_tibble,
       vector_match = vector_match))  
}

References


1
Altarawneh HN, Chemaitelly H, Ayoub HH, et al. Effects of Previous Infection and Vaccination on Symptomatic Omicron Infections. New England Journal of Medicine 2022. DOI:10.1056/nejmoa2203965.