Datos de muestra

Un forest plot (diagrama de bosque) muestra el efecto estimado y el intervalo de confianza de varios estudios o variables en un mismo gráfico. Se utiliza habitualmente en metaanálisis, mostrando el resultado de cada estudio y la estimación global, y también para mostrar los odds ratios o los hazard ratios de un modelo de regresión, como los modelos de Cox que se utilizan en el análisis de supervivencia junto a las curvas de Kaplan-Meier.

En este tutorial vamos a utilizar los siguientes datos, que contienen el odds ratio de siete estudios y su estimación global, los límites inferior y superior de los intervalos de confianza y el peso de cada estudio en el metaanálisis. Ten en cuenta que convertimos los estudios en un factor con los niveles invertidos, de modo que se mostrarán de arriba abajo en el mismo orden.

df <- data.frame(study = c("Estudio A", "Estudio B", "Estudio C", "Estudio D",
                           "Estudio E", "Estudio F", "Estudio G", "Global"),
                 OR = c(0.82, 0.64, 1.10, 0.71, 0.93, 0.58, 0.77, 0.76),
                 lower = c(0.61, 0.42, 0.79, 0.55, 0.70, 0.36, 0.60, 0.68),
                 upper = c(1.10, 0.97, 1.53, 0.92, 1.24, 0.93, 0.99, 0.85),
                 weight = c(14, 9, 11, 18, 15, 7, 26, NA))

df$study <- factor(df$study, levels = rev(df$study))

Forest plot básico

Para crear un forest plot en ggplot2 tendrás que pasar las estimaciones a x y los estudios a y. Luego, añade los intervalos de confianza como barras de error horizontales con geom_errorbar, pasando los límites a xmin y xmax, y las estimaciones con geom_point.

# install.packages("ggplot2")
library(ggplot2)

ggplot(df, aes(x = OR, y = study)) +
  geom_errorbar(aes(xmin = lower, xmax = upper), width = 0.2) +
  geom_point()

Forest plot básico en R con ggplot2

Ten en cuenta que también puedes utilizar geom_pointrange, que dibuja el punto y el intervalo a la vez, pero sin las líneas verticales en los extremos.

Línea de no efecto

Forest plot con la línea de no efecto en ggplot2

La línea de no efecto permite identificar qué estudios son estadísticamente significativos, ya que sus intervalos de confianza no la cruzan. Para ratios, como los odds ratios o los hazard ratios, la línea se debe colocar en 1, mientras que para diferencias, como las diferencias de medias, se debe colocar en 0. Añádela con geom_vline antes que el resto de capas, de modo que se dibuje detrás de ellas.

ggplot(df, aes(x = OR, y = study)) +
  geom_vline(xintercept = 1, linetype = "dashed") +
  geom_errorbar(aes(xmin = lower, xmax = upper), width = 0.2) +
  geom_point()

Escala logarítmica

Los ratios no son simétricos: un odds ratio de 0.5 representa el mismo efecto que un odds ratio de 2, pero en sentido contrario. Por eso se recomienda mostrar los ratios en escala logarítmica con scale_x_log10, de modo que los intervalos se vean simétricos alrededor de la estimación. También puedes elegir las marcas del eje con breaks.

ggplot(df, aes(x = OR, y = study)) +
  geom_vline(xintercept = 1, linetype = "dashed") +
  geom_errorbar(aes(xmin = lower, xmax = upper), width = 0.2) +
  geom_point() +
  scale_x_log10(breaks = c(0.4, 0.6, 0.8, 1, 1.25, 1.6))

Forest plot con escala logarítmica para odds ratios en ggplot2

Tamaño por peso y estimación global

En un metaanálisis el tamaño de los puntos suele representar el peso de cada estudio y la estimación global se muestra con una forma diferente, normalmente un rombo. Para ello, divide los datos en los estudios y la estimación global, pasa los pesos a size y añade la estimación global como una nueva capa con shape = 18. Ten en cuenta que scale_y_discrete mantiene la estimación global en la parte inferior, ya que de lo contrario ggplot2 la colocaría al final de la escala. Consulta la lista de formas en ggplot2 para otras opciones.

studies <- df[df$study != "Global", ]
overall <- df[df$study == "Global", ]

ggplot(studies, aes(x = OR, y = study)) +
  geom_vline(xintercept = 1, linetype = "dashed") +
  geom_errorbar(aes(xmin = lower, xmax = upper), width = 0.2) +
  geom_point(aes(size = weight), shape = 15) +
  geom_point(data = overall, shape = 18, size = 7, color = "#E76F51") +
  scale_x_log10(breaks = c(0.4, 0.6, 0.8, 1, 1.25, 1.6)) +
  scale_y_discrete(limits = levels(df$study)) +
  theme(legend.position = "none")

Forest plot con el tamaño de los puntos por peso y la estimación global como un rombo en ggplot2

Forest plot con una tabla de valores

Es muy habitual mostrar los valores de las estimaciones y los intervalos de confianza junto al gráfico. Puedes crear una columna con el texto formateado y añadirla con geom_text a la derecha del gráfico, aumentando los límites del eje X y permitiendo los textos fuera del panel con clip = "off".

df$label <- sprintf("%.2f [%.2f, %.2f]", df$OR, df$lower, df$upper)
studies <- df[df$study != "Global", ]
overall <- df[df$study == "Global", ]

ggplot(studies, aes(x = OR, y = study)) +
  geom_vline(xintercept = 1, linetype = "dashed") +
  geom_errorbar(aes(xmin = lower, xmax = upper), width = 0.2) +
  geom_point(aes(size = weight), shape = 15, color = "#264653") +
  geom_point(data = overall, shape = 18, size = 7, color = "#E76F51") +
  geom_text(data = df, aes(x = 2.2, label = label), hjust = 0) +
  annotate("text", x = 2.2, y = 8.7, label = "OR [IC 95%]", hjust = 0, fontface = "bold") +
  scale_x_log10(breaks = c(0.4, 0.6, 0.8, 1, 1.25, 1.6)) +
  scale_y_discrete(limits = levels(df$study)) +
  coord_cartesian(xlim = c(0.35, 1.7), clip = "off") +
  theme_minimal() +
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        plot.margin = margin(10, 120, 10, 10)) +
  labs(x = "Odds ratio (escala logarítmica)", y = NULL)

Forest plot con una tabla de odds ratios e intervalos de confianza en ggplot2

También puedes comparar dos valores por grupo con un gráfico de dumbbell.

MASTER - STATISTICS DOT COM

Master Statistics

Aprende estadística desde lo básico hasta técnicas avanzadas, explicado con claridad

Ir al sitio
R PACKAGES IO

R Packages

Explora y descubre miles de paquetes, funciones y datasets de R

Ir al sitio

También te puede interesar