Edad FET

Comenzamos cargandos las librerias necesarias que son metafor y el tidyverse, instalandolas previamente si aún no lo están:

if (!require("metafor")) install.packages("metafor")
Loading required package: metafor
Loading required package: Matrix
Loading required package: metadat
Loading required package: numDeriv

Loading the 'metafor' package (version 4.8-0). For an
introduction to the package please type: help(metafor)
if (!require("tidyverse")) install.packages("tidyverse")
Loading required package: tidyverse
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.2     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.4     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ tidyr::expand() masks Matrix::expand()
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
✖ tidyr::pack()   masks Matrix::pack()
✖ tidyr::unpack() masks Matrix::unpack()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(metafor)
library(tidyverse)

En primer lugar cargamos una hoja concreta del fichero excel de medias y desviaciones:

hojaActual="Edad_FET"
datos <- readxl::read_excel("mediaydesviacion.xlsx", sheet = hojaActual) %>% 
  mutate(SEI=SD/sqrt(N))
datos
# A tibble: 9 × 5
  Autor                                  Mean    SD     N   SEI
  <chr>                                 <dbl> <dbl> <dbl> <dbl>
1 Arnold et al (Aneurismas)              68.3   8.9    74 1.03 
2 Arnold et al (Disecciones Crónicas)    56.9  12.9    49 1.84 
3 Di Eusanio et al                       65.6   7.3    21 1.59 
4 Koizumi et al                          76.2   5.9    60 0.762
5 Panfilov et al                         55.7   1.9    26 0.373
6 Shrestha et al (Aneurismas)            59.8  12.9    82 1.42 
7 Shrestha et al (Disecciones Crónicas)  59.9  12.8    69 1.54 
8 Verhoye et al                          64    11      94 1.13 
9 Weiss et al                            59    11      41 1.72 

En este caso tenemos cuatro columnas con autor, valor medio, desviación y n (tamaño de muestra) obtenidos por una serie de trabajos. Queremos hacer una metaanálisis de medias. Para ello usamos la función rma de la librería metafor, que nos permite hacer metaanálisis de distintos tipos. En este caso usamos el método “REML” (Restricted Maximum Likelihood) para un modelo de efectos aleatorios, y especificamos que los datos son medias (yi=Mean) y desviaciones estándar (sei=SD), y el tamaño de muestra (ni=N).

res <- rma(yi=Mean, sei=SEI, ni=N, data=datos, method="REML")
res

Random-Effects Model (k = 9; tau^2 estimator: REML)

tau^2 (estimated amount of total heterogeneity): 41.7356 (SE = 21.7605)
tau (square root of estimated tau^2 value):      6.4603
I^2 (total heterogeneity / total variability):   97.67%
H^2 (total variability / sampling variability):  42.94

Test for Heterogeneity:
Q(df = 8) = 671.9872, p-val < .0001

Model Results:

estimate      se     zval    pval    ci.lb    ci.ub      
 62.8741  2.1992  28.5893  <.0001  58.5637  67.1844  *** 

---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

El resultado nos da la media global estimada, su error estándar, el intervalo de confianza al 95% y el valor p asociado. También nos da información sobre la heterogeneidad entre estudios (Q, I^2, H^2).

Esto queda más bonito si lo representamos gráficamente con un forest plot:

forest(res, slab=datos$Autor, xlab="Media", mlab="Media global (IC 95%)")
abline(v=res$b, col="red")
text(res$b, -1, round(res$b,2), col="red", pos=4)

El forest plot muestra las medias individuales de cada estudio con sus intervalos de confianza, así como la media global estimada (línea roja) con su intervalo de confianza.

Para evaluar la posible presencia de sesgo de publicación, podemos añadir un funnel plot:

funnel(res, xlab="Media", ylab="Error estándar")
abline(v=res$b, col="red")

Para interpretarlo: si los puntos están simétricamente distribuidos alrededor de la media global, es menos probable que haya sesgo de publicación. Si hay asimetría, podría indicar que estudios con ciertos resultados (por ejemplo, resultados no significativos) no han sido publicados.

Finalmente, podemos realizar un test estadístico para evaluar la asimetría del funnel plot, como el test de Egger:

regtest(res, model="rma", predictor="sei")

Regression Test for Funnel Plot Asymmetry

Model:     mixed-effects meta-regression model
Predictor: standard error

Test for Funnel Plot Asymmetry: z = -0.7664, p = 0.4435
Limit Estimate (as sei -> 0):   b =  67.6408 (CI: 54.6603, 80.6212)

El resultado del test de Egger nos da un valor p que nos indica si hay evidencia estadística de asimetría en el funnel plot. Un valor p menor a 0.05 suele interpretarse como indicativo de sesgo de publicación.