Cause delle distribuzioni bimodali all'avvio di un modello di meta-analisi


8

Aiuto un collega ad avviare un modello a effetti misti di meta-analisi usando il framework del pacchetto metafor R creato da @Wolfgang.

È interessante e preoccupante che per uno dei coefficienti del modello ottenga una distribuzione bimodale durante il bootstrap (vedi il pannello in basso a destra della figura sotto).

Immagino che una delle cause principali potrebbe essere il fatto che durante l'avvio del bootstrap, diciamo che metà dei modelli convergono in una soluzione locale e l'altra metà in un'altra. Ho provato a mettere a punto l'algoritmo di convergenza come suggerito in questa documentazione metafor - Problemi di convergenza con la funzione rma () . Inoltre, ho provato altri algoritmi di convergenza come bobyqae newuoacome suggerito nella documentazione di aiuto della funzione rma.mv , ma ho ottenuto la stessa risposta bimodale.

Ho anche cercato di eliminare alcuni dei potenziali valori anomali dal gruppo problematico come suggerito in Come interpretare la distribuzione multimodale della correlazione avviata , ma senza risultati.

Non sono riuscito a trovare un modo per riprodurlo, quindi ho caricato i dati su un repository GitHub (anche i collegamenti nella sezione di codice seguente dovrebbero caricare nel tuo ambiente tutto ciò che è necessario per testare il caso). Eseguo il bootstrap su un cluster Linux come processo array (per ogni evenienza, lo script shell è job.sh , che esegue su ogni CPU lo script R bootstrap.r che esegue il modello descritto di seguito). Una singola corsa richiede 2-3 minuti. Si noti che il bootstrap 100 volte è anche sufficiente per rilevare la risposta bimodale. Di seguito è riportato un esempio per 1000 iterazioni. Conosco R e altri metodi, ma non molto con la meta-analisi.

Gradirei aiuto per capire se la distribuzione bimodale è ok (anche se potrebbe essere dovuta a problemi di convergenza) e, in caso contrario, cosa si può fare al riguardo? (oltre a quello che ho già provato)

Di seguito: confronto dei coefficienti dal bootstrap (linee rosse) e da una singola corsa del modello completo (linee blu). Gli istogrammi descrivono le distribuzioni bootstrap per ciascun coefficiente. Il campionamento dei dati per il bootstrap è stato fatto come selezione con sostituzione da ciascun gruppo / combinazione formata dai due effetti fissi. Le dimensioni dei campioni grezzi sono:

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)

Creato il 02-05-2019 dal pacchetto reprex (v0.2.1)

Il modello va così:

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))

Informazioni sulla sessione 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)

Risposte:


6

Grazie per aver fornito i dati e il codice. Ho rimontato il modello con cui stai lavorando e il secondo componente di varianza (per il quale cor_matè specificato) si sposta a un valore davvero grande, il che è strano. Tuttavia, la profilazione di questo componente di varianza (con profile(rmamv_model, sigma2=2)) non indica alcun problema, quindi non credo che si tratti di un problema di convergenza. Invece, penso che il problema si presenti perché il modello non include un effetto casuale a livello di stima (che in pratica dovrebbe includere ogni modello meta-analitico). Quindi, suggerirei di adattarsi:

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")

I risultati sembrano molto più ragionevoli. Sospetto che ciò potrebbe anche risolvere il problema con la distribuzione bootstrap bimodale di quest'ultimo coefficiente.


1
Grazie @ Wolfgang! Risolto il problema! I coefficienti sembrano ora molto più ragionevoli (si adattano alle aspettative / teoria) e ha anche risolto il problema della distribuzione bimodale. Dal momento che hai familiarità con tali problemi e se li hai a portata di mano, sarebbe meraviglioso se puoi anche fornire alcuni riferimenti peer-reviewed che supportano l'idea di incorporare un effetto casuale a livello di osservazione. Ho trovato Harrison, 2014 , ma sembra particolare per i dati di conteggio. Grazie ancora!
Valentin,

Non conosco un riferimento che lo dica letteralmente, ma potresti dare un'occhiata a: metafor-project.org/doku.php/…
Wolfgang

1

Senza avere accesso a un esempio riproducibile è estremamente difficile dare una risposta definitiva a questo comportamento di bootstrap. Supponendo che non ci siano davvero valori anomali, sospetto che osserviamo un caso lieve del fenomeno di Stein, specialmente perché una metodologia a effetti misti suggerisce che ci sia un certo raggruppamento nei nostri dati.

Detto questo, suggerirei di andare avanti e guardare alcune delle sequenze dai valori "insoliti" di f2f2_3:f1f1_2interazione, dove ci sono valori molto diversi, e indagare sulla distribuzione marginale di questi due sottocampioni casuali. Ad esempio in alcuni casi, f2f2_3:f1f1_2è ben al di sotto1 mentre il modello stimato suggerisce valori vicini a 2.4. La distribuzione marginale è simile? C'è un caso di sovrapposizione insufficiente? Forse il bootstrap "semplice" è inappropriato e dobbiamo stratificare il campione a portata di mano rispetto ad alcuni dei fattori.


Grazie per il tuo contributo, i dati erano disponibili e pronti per essere caricati nei collegamenti forniti. Il codice e i dati dovrebbero essere ancora riproducibili.
Valentin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.