Come ottenere valori p aggregati sui test eseguiti in più set di dati imputati?


11

Usando Amelia in R, ho ottenuto più set di dati imputati. Successivamente, ho eseguito un test di misure ripetute in SPSS. Ora voglio unire i risultati dei test. So di poter usare le regole di Rubin (implementate attraverso qualsiasi pacchetto di imputazione multipla in R) per raggruppare mezzi ed errori standard, ma come posso mettere in comune i valori p? È possibile? Esiste una funzione in R per farlo? Grazie in anticipo.


Potresti voler controllare le informazioni sulla meta-analisi del valore p. Un buon punto di partenza: en.wikipedia.org/wiki/Fisher%27s_method
user29889

Risposte:


13

, è possibile e, sì, ci sono Rfunzioni che lo fanno. Invece di calcolare manualmente i valori p delle analisi ripetute, è possibile utilizzare il pacchetto Zelig, a cui si fa riferimento anche nella vignetta del pacchetto Amelia( per un metodo più informativo vedere il mio aggiornamento di seguito ). AmeliaUserò un esempio dal -vignette per dimostrare questo:

library("Amelia")
data(freetrade)
amelia.out <- amelia(freetrade, m = 15, ts = "year", cs = "country")

library("Zelig")
zelig.fit <- zelig(tariff ~ pop + gdp.pc + year + polity, data = amelia.out$imputations, model = "ls", cite = FALSE)
summary(zelig.fit)

Questo è l'output corrispondente inclusi i valori :p

  Model: ls
  Number of multiply imputed data sets: 15 

Combined results:

Call:
lm(formula = formula, weights = weights, model = F, data = data)

Coefficients:
                Value Std. Error t-stat  p-value
(Intercept)  3.18e+03   7.22e+02   4.41 6.20e-05
pop          3.13e-08   5.59e-09   5.59 4.21e-08
gdp.pc      -2.11e-03   5.53e-04  -3.81 1.64e-04
year        -1.58e+00   3.63e-01  -4.37 7.11e-05
polity       5.52e-01   3.16e-01   1.75 8.41e-02

For combined results from datasets i to j, use summary(x, subset = i:j).
For separate results, use print(summary(x), subset = i:j).

zeligpuò adattarsi a una serie di modelli diversi dai minimi quadrati.

Per ottenere intervalli di confidenza e gradi di libertà per le tue stime puoi utilizzare mitools:

library("mitools")
imp.data <- imputationList(amelia.out$imputations)
mitools.fit <- MIcombine(with(imp.data, lm(tariff ~ polity + pop + gdp.pc + year)))
mitools.res <- summary(mitools.fit)
mitools.res <- cbind(mitools.res, df = mitools.fit$df)
mitools.res

Questo ti darà intervalli di confidenza e proporzione della varianza totale che è attribuibile ai dati mancanti:

              results       se    (lower    upper) missInfo    df
(Intercept)  3.18e+03 7.22e+02  1.73e+03  4.63e+03     57 %  45.9
pop          3.13e-08 5.59e-09  2.03e-08  4.23e-08     19 % 392.1
gdp.pc      -2.11e-03 5.53e-04 -3.20e-03 -1.02e-03     21 % 329.4
year        -1.58e+00 3.63e-01 -2.31e+00 -8.54e-01     57 %  45.9
polity       5.52e-01 3.16e-01 -7.58e-02  1.18e+00     41 %  90.8

Ovviamente puoi semplicemente combinare i risultati interessanti in un oggetto:

combined.results <- merge(mitools.res, zelig.res$coefficients[, c("t-stat", "p-value")], by = "row.names", all.x = TRUE)

Aggiornare

Dopo aver giocato un po ', ho trovato un modo più flessibile per ottenere tutte le informazioni necessarie usando il micepacchetto. Affinché ciò funzioni, è necessario modificare la funzione del pacchetto as.mids(). Usa la versione di Gerko pubblicata nella mia domanda di follow-up :

as.mids2 <- function(data2, .imp=1, .id=2){
  ini <- mice(data2[data2[, .imp] == 0, -c(.imp, .id)], m = max(as.numeric(data2[, .imp])), maxit=0)
  names  <- names(ini$imp)
  if (!is.null(.id)){
    rownames(ini$data) <- data2[data2[, .imp] == 0, .id]
  }
  for (i in 1:length(names)){
    for(m in 1:(max(as.numeric(data2[, .imp])))){
      if(!is.null(ini$imp[[i]])){
        indic <- data2[, .imp] == m & is.na(data2[data2[, .imp]==0, names[i]])
        ini$imp[[names[i]]][m] <- data2[indic, names[i]]
      }
    } 
  }
  return(ini)
}

Con questo definito, è possibile continuare ad analizzare i set di dati imputati:

library("mice")
imp.data <- do.call("rbind", amelia.out$imputations)
imp.data <- rbind(freetrade, imp.data)
imp.data$.imp <- as.numeric(rep(c(0:15), each = nrow(freetrade)))
mice.data <- as.mids2(imp.data, .imp = ncol(imp.data), .id = NULL)

mice.fit <- with(mice.data, lm(tariff ~ polity + pop + gdp.pc + year))
mice.res <- summary(pool(mice.fit, method = "rubin1987"))

Questo vi darà tutti i risultati che si ottengono utilizzando Zelige mitoolspiù:

                  est       se     t    df Pr(>|t|)     lo 95     hi 95 nmis   fmi lambda
(Intercept)  3.18e+03 7.22e+02  4.41  45.9 6.20e-05  1.73e+03  4.63e+03   NA 0.571  0.552
pop          3.13e-08 5.59e-09  5.59 392.1 4.21e-08  2.03e-08  4.23e-08    0 0.193  0.189
gdp.pc      -2.11e-03 5.53e-04 -3.81 329.4 1.64e-04 -3.20e-03 -1.02e-03    0 0.211  0.206
year        -1.58e+00 3.63e-01 -4.37  45.9 7.11e-05 -2.31e+00 -8.54e-01    0 0.570  0.552
polity       5.52e-01 3.16e-01  1.75  90.8 8.41e-02 -7.58e-02  1.18e+00    2 0.406  0.393

Nota, usando pool()puoi anche calcolare i valori con regolato per piccoli campioni omettendo il parametro. Ciò che è ancora meglio, ora puoi anche calcolare e confrontare i modelli nidificati:d f R 2pdfmethodR2

pool.r.squared(mice.fit)

mice.fit2 <- with(mice.data, lm(tariff ~ polity + pop + gdp.pc))
pool.compare(mice.fit, mice.fit2, method = "Wald")$pvalue

1
Grande risposta, volevo solo far notare un leggero errore di battitura, penso che volevi dire: mice.res <- summary(pool(mice.fit, method = "rubin1987")).
FrankD

Buona pesca. Ho corretto l'errore di battitura.
crsh

8

Normalmente prenderesti il ​​valore p applicando le regole di Rubin su parametri statistici convenzionali come i pesi di regressione. Pertanto, spesso non è necessario raggruppare direttamente i valori p. Inoltre, la statistica del rapporto di probabilità può essere raggruppata per confrontare i modelli. Le procedure di pooling per altre statistiche sono disponibili nel mio libro Imposizione flessibile dei dati mancanti, capitolo 6.

Nei casi in cui non esiste una distribuzione o un metodo noti, esiste una procedura non pubblicata da Licht e Rubin per i test unilaterali. Ho usato questa procedura per riunire i valori p della wilcoxon()procedura, ma è generale e semplice adattarsi ad altri usi.

Utilizzare la procedura di seguito SOLO se tutto il resto fallisce, per ora sappiamo poco delle sue proprietà statistiche.

lichtrubin <- function(fit){
    ## pools the p-values of a one-sided test according to the Licht-Rubin method
    ## this method pools p-values in the z-score scale, and then transforms back 
    ## the result to the 0-1 scale
    ## Licht C, Rubin DB (2011) unpublished
    if (!is.mira(fit)) stop("Argument 'fit' is not an object of class 'mira'.")
    fitlist <- fit$analyses
        if (!inherits(fitlist[[1]], "htest")) stop("Object fit$analyses[[1]] is not an object of class 'htest'.")
    m <- length(fitlist)
    p <- rep(NA, length = m)
    for (i in 1:m) p[i] <- fitlist[[i]]$p.value
    z <- qnorm(p)  # transform to z-scale
    num <- mean(z)
    den <- sqrt(1 + var(z))
    pnorm( num / den) # average and transform back
}

@ Stef van Buuren cosa intendi con 'prendi il valore p applicando le regole di Rubin su parametri statistici convenzionali come i pesi di regressione'? In che modo la pool() funzione nel pacchetto (che è comunque eccellente ) arriva al valore p raggruppato?
Llewmills
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.