Causas de las distribuciones bimodales al iniciar un modelo de metanálisis

8

Ayudo a un colega a poner en marcha un modelo de meta-análisis de efectos mixtos utilizando el marco del paquete metafor R escrito por @Wolfgang.

Interesante y preocupante, para uno de los coeficientes del modelo obtengo una distribución bimodal al arrancar (ver el panel inferior derecho de la figura a continuación).

Supongo que una de las causas principales podría ser el hecho de que, al arrancar, la mitad de los modelos convergen en una solución local y la otra mitad en otra. Traté de ajustar el algoritmo de convergencia como se sugiere en esta documentación de metafor - Problemas de convergencia con la función rma () . Además, probé otros algoritmos de convergencia como bobyqay newuoacomo se sugiere en la documentación de ayuda de la función rma.mv , pero obtuve la misma respuesta bimodal.

También intenté eliminar algunos de los posibles valores atípicos del grupo problemático como se sugiere en Cómo interpretar la distribución multimodal de la correlación bootstrapped , pero fue en vano.

No pude encontrar una manera de reproducir esto, así que cargué datos en un repositorio de GitHub (también los enlaces en la sección de código a continuación deberían cargar en su entorno todo lo que se necesita para probar el caso). Ejecuto el bootstrapping en un clúster de Linux como un trabajo de matriz (por si acaso, el script de shell es job.sh , que ejecuta en cada CPU el script R bootstrap.r que ejecuta el modelo descrito a continuación). Una sola carrera toma 2-3 minutos. Tenga en cuenta que el arranque 100 veces también es suficiente para detectar la respuesta bimodal. A continuación se muestra un ejemplo para 1000 iteraciones. Estoy familiarizado con R y otros métodos, pero no tanto con el metanálisis.

Le agradecería ayuda para comprender si la distribución bimodal está bien (aunque podría deberse a problemas de convergencia) y si no, ¿qué se puede hacer al respecto? (además de lo que ya probé)

A continuación: comparación de los coeficientes de bootstrapping (líneas rojas) y de un solo modelo completo (líneas azules). Los histogramas representan las distribuciones de arranque para cada coeficiente. El muestreo de los datos para el arranque se realizó como selección con reemplazo de cada grupo / combinación formada por los dos efectos fijos. Sus tamaños de muestra sin procesar son:

table(dt$f1, dt$f2)
#>       
#>        f2_1 f2_2 f2_3
#>   f1_1  177  174   41
#>   f1_2  359  363  107
library(data.table)
library(ggplot2)
library(metafor)
#> Loading required package: Matrix
#> Loading 'metafor' package (version 2.0-0). For an overview 
#> and introduction to the package please type: help(metafor).

load(url("https://github.com/valentinitnelav/test/raw/master/bimodal_distrib_boot/coef_boot_dt_1010.rda"))
load(url("https://github.com/valentinitnelav/test/raw/master/bimodal_distrib_boot/rmamv_model.rda"))
load(url("https://github.com/valentinitnelav/test/raw/master/bimodal_distrib_boot/data.rda"))

coef_dt <- data.frame(estim = rmamv_model[["beta"]])
coef_dt$coef_name <- rownames(coef_dt)
coef_dt <- rbind(coef_dt,
                 coef_boot_dt[, .(estim = mean(coef)), by = coef_name])
coef_dt[, gr := rep(c("estim_model", "estim_boot"), each = 6)]

ggplot(data = coef_boot_dt,
       aes(x = coef,
           group = coef_name)) +
  geom_histogram(bins = 100) +
  geom_vline(aes(xintercept = estim,
                 group = gr,
                 color = gr),
             lwd = 1,
             data = coef_dt) +
  facet_wrap(vars(coef_name), ncol = 2)

Creado el 02/05/2019 por el paquete reprex (v0.2.1)

El modelo dice así:

rmamv_model <- rma.mv(y ~ f2:f1 - 1,
                  V = var_y,
                  random = list(~ 1|r1,
                                ~ 1|r2),
                  R = list(r2 = cor_mat),
                  data = dt,
                  method = "REML",
                  # Tune the convergence algorithm / optimizer
                  control = list(optimizer = "nlminb",
                                 iter.max = 1000,
                                 step.min = 0.4,
                                 step.max = 0.5))

Información de la sesión R:

devtools::session_info()
#> - Session info ----------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.5.2 (2018-12-20)
#>  os       Windows 7 x64 SP 1          
#>  system   x86_64, mingw32             
#>  ui       RTerm                       
#>  language (EN)                        
#>  collate  English_United States.1252  
#>  ctype    English_United States.1252               
#>  date     2019-05-02                  
#> 
#> - Packages --------------------------------------------------------------
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [1] CRAN (R 3.5.2)
#>  backports     1.1.3   2018-12-14 [1] CRAN (R 3.5.2)
#>  callr         3.2.0   2019-03-15 [1] CRAN (R 3.5.3)
#>  cli           1.1.0   2019-03-19 [1] CRAN (R 3.5.3)
#>  colorspace    1.4-1   2019-03-18 [1] CRAN (R 3.5.3)
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.5.1)
#>  curl          3.3     2019-01-10 [1] CRAN (R 3.5.2)
#>  data.table  * 1.12.0  2019-01-13 [1] CRAN (R 3.5.2)
#>  desc          1.2.0   2018-05-01 [1] CRAN (R 3.5.1)
#>  devtools      2.0.1   2018-10-26 [1] CRAN (R 3.5.1)
#>  digest        0.6.18  2018-10-10 [1] CRAN (R 3.5.1)
#>  dplyr         0.8.0.1 2019-02-15 [1] CRAN (R 3.5.2)
#>  evaluate      0.13    2019-02-12 [1] CRAN (R 3.5.2)
#>  fs            1.2.7   2019-03-19 [1] CRAN (R 3.5.3)
#>  ggplot2     * 3.1.0   2018-10-25 [1] CRAN (R 3.5.1)
#>  glue          1.3.1   2019-03-12 [1] CRAN (R 3.5.2)
#>  gtable        0.2.0   2016-02-26 [1] CRAN (R 3.5.1)
#>  highr         0.8     2019-03-20 [1] CRAN (R 3.5.3)
#>  htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.5.1)
#>  httr          1.4.0   2018-12-11 [1] CRAN (R 3.5.2)
#>  knitr         1.22    2019-03-08 [1] CRAN (R 3.5.2)
#>  labeling      0.3     2014-08-23 [1] CRAN (R 3.5.0)
#>  lattice       0.20-38 2018-11-04 [2] CRAN (R 3.5.2)
#>  lazyeval      0.2.2   2019-03-15 [1] CRAN (R 3.5.3)
#>  magrittr      1.5     2014-11-22 [1] CRAN (R 3.5.1)
#>  Matrix      * 1.2-15  2018-11-01 [2] CRAN (R 3.5.2)
#>  memoise       1.1.0   2017-04-21 [1] CRAN (R 3.5.1)
#>  metafor     * 2.0-0   2017-06-22 [1] CRAN (R 3.5.2)
#>  mime          0.6     2018-10-05 [1] CRAN (R 3.5.1)
#>  munsell       0.5.0   2018-06-12 [1] CRAN (R 3.5.1)
#>  nlme          3.1-137 2018-04-07 [2] CRAN (R 3.5.2)
#>  pillar        1.3.1   2018-12-15 [1] CRAN (R 3.5.2)
#>  pkgbuild      1.0.3   2019-03-20 [1] CRAN (R 3.5.3)
#>  pkgconfig     2.0.2   2018-08-16 [1] CRAN (R 3.5.1)
#>  pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.5.1)
#>  plyr          1.8.4   2016-06-08 [1] CRAN (R 3.5.1)
#>  prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.5.1)
#>  processx      3.3.0   2019-03-10 [1] CRAN (R 3.5.3)
#>  ps            1.3.0   2018-12-21 [1] CRAN (R 3.5.2)
#>  purrr         0.3.2   2019-03-15 [1] CRAN (R 3.5.3)
#>  R6            2.4.0   2019-02-14 [1] CRAN (R 3.5.2)
#>  Rcpp          1.0.1   2019-03-17 [1] CRAN (R 3.5.3)
#>  remotes       2.0.2   2018-10-30 [1] CRAN (R 3.5.1)
#>  rlang         0.3.4   2019-04-07 [1] CRAN (R 3.5.3)
#>  rmarkdown     1.12    2019-03-14 [1] CRAN (R 3.5.3)
#>  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.5.1)
#>  scales        1.0.0   2018-08-09 [1] CRAN (R 3.5.1)
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.5.1)
#>  stringi       1.4.3   2019-03-12 [1] CRAN (R 3.5.2)
#>  stringr       1.4.0   2019-02-10 [1] CRAN (R 3.5.1)
#>  tibble        2.1.1   2019-03-16 [1] CRAN (R 3.5.3)
#>  tidyselect    0.2.5   2018-10-11 [1] CRAN (R 3.5.1)
#>  usethis       1.4.0   2018-08-14 [1] CRAN (R 3.5.1)
#>  withr         2.1.2   2018-03-15 [1] CRAN (R 3.5.1)
#>  xfun          0.5     2019-02-20 [1] CRAN (R 3.5.2)
#>  xml2          1.2.0   2018-01-24 [1] CRAN (R 3.5.1)
#>  yaml          2.2.0   2018-07-25 [1] CRAN (R 3.5.1)
Valentin
fuente

Respuestas:

6

Gracias por proporcionar los datos y el código. Volví a ajustar el modelo con el que está trabajando y el segundo componente de varianza (para el que cor_matse especifica) deriva a un valor realmente grande, lo cual es extraño. Sin embargo, el perfil de este componente de varianza (con profile(rmamv_model, sigma2=2)) no indica problemas, por lo que no creo que sea un problema de convergencia. En cambio, creo que el problema surge porque el modelo no incluye un efecto aleatorio a nivel de estimación (que básicamente debería incluir todo modelo metaanalítico). Por lo tanto, sugeriría encajar:

dt$id <- 1:nrow(dt)

res <- rma.mv(y ~ f2:f1 - 1,
              V = var_y,
              random = list(~ 1|r1,
                            ~ 1|r2, 
                            ~ 1|id),
              R = list(r2 = cor_mat),
              data = dt,
              method = "REML")

Los resultados parecen mucho más razonables. Sospecho que esto también podría resolver el problema con la distribución de arranque bimodal de ese último coeficiente.

Wolfgang
fuente
1
Gracias @ Wolfgang! Se solucionó el problema! Los coeficientes ahora parecen mucho más razonables (se ajustan a las expectativas / teoría) y también resolvió el problema de distribución bimodal. Dado que está muy familiarizado con estos problemas y si los tiene a mano, sería maravilloso si también puede proporcionar algunas referencias revisadas por pares que respalden la idea de incorporar un efecto aleatorio a nivel de observación. Encontré Harrison, 2014 , pero parece particular para los datos de conteo. Muchas gracias de nuevo!
Valentín
No conozco una referencia que literalmente lo diga, pero es posible que desee echar un vistazo a: metafor-project.org/doku.php/…
Wolfgang
1

Sin tener acceso a un ejemplo reproducible es extremadamente difícil dar una respuesta definitiva a este comportamiento de arranque. Suponiendo que de hecho no hay valores atípicos, sospecho que observamos un caso leve del fenómeno de Stein, especialmente porque una metodología de efectos mixtos sugiere que agrupamos algunos de nuestros datos.

Habiendo dicho lo anterior, sugeriría seguir adelante y observar algunas de las corridas desde los valores "inusuales" de f2f2_3:f1f1_2interacción, donde hay valores muy diferentes, e investigar la distribución marginal de estas dos submuestras aleatorias. Por ejemplo, en algunos casos, f2f2_3:f1f1_2está muy por debajo1 mientras que el modelo estimado sugiere valores cercanos a 2.4. ¿La distribución marginal es similar? ¿Hay algún caso de superposición insuficiente? Tal vez el bootstrap "simple" es inapropiado y necesitamos estratificar la muestra en cuestión con respecto a algunos de los factores.

usεr11852
fuente
Gracias por su aporte, los datos estaban disponibles y listos para cargar en los enlaces provistos. El código y los datos aún deben ser reproducibles.
Valentín