Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Improved meta-analysis forest plotting #272

Open
bwiernik opened this issue Mar 4, 2023 · 0 comments
Open

Improved meta-analysis forest plotting #272

bwiernik opened this issue Mar 4, 2023 · 0 comments
Labels
Enhancement 💥 New feature or request

Comments

@bwiernik
Copy link
Contributor

bwiernik commented Mar 4, 2023

Related to easystats/insight#726

We should plot the aggregate results from a meta-analysis using a diamond for the confidence interval using geom_polygon() and also include the prediction interval.

Example:

library(tidyverse)
library(metafor)

delta <- .5
tau <- .2
diamond_height <- .3

studies <- tibble(
  study = LETTERS,
  ni = round(runif(n = length(study), min = 100, max = 200)),
  true_i = delta + rnorm(n = length(study), mean = 0, sd = tau),
  yi = rnorm(n = length(study), mean = true_i, sd = sqrt(psychmeta::var_error_d(d = true_i, n1 = ni, n2 = ni))),
  se = sqrt(psychmeta::var_error_d(d = yi, n1 = ni, n2 = ni)),
  ci.lb = yi - qnorm(.975) * se,
  ci.ub = yi + qnorm(.975) * se
)

plot_dat <- bind_rows(
  Studies = studies,
  Aggregate = rma(yi ~ 1, sei = se, data = studies, method = "REML", test = "knha") |> 
    predict() |> 
    as.data.frame() |> 
    rename(yi = pred) |> 
    mutate(study = "Random effects"),
  .id = "type"
) |> 
  mutate(type = as_factor(type), study = as_factor(study), ypos = datawizard::reverse(as.integer(study)))

ggplot(plot_dat) +
  aes(y = forcats::fct_rev(study), x = yi, xmin = ci.lb, xmax = ci.ub) +
  geom_linerange(data = \(x) filter(x, type == "Studies")) +
  geom_point(data = \(x) filter(x, type == "Studies")) +
  geom_linerange(
    aes(xmin = pi.lb, xmax = pi.ub),
    data = \(x) filter(x, type == "Aggregate"),
    linetype = "twodash"
  ) +
  geom_polygon(
    aes(x = x.diamond, y = y.diamond, group = study),
    data = \(x) filter(x, type == "Aggregate") |> 
      group_by(study) |> 
      reframe(
        x.diamond = c(ci.ub, yi, ci.lb, yi),
        y.diamond = ypos + c(0, diamond_height, 0, -diamond_height)
      ),
    inherit.aes = FALSE
  ) +
  labs(y = NULL, x = "Standardized mean difference") +
  scale_y_discrete(drop = FALSE) + # this one is key!
  see::theme_modern() +
  theme(strip.background = element_blank(), strip.text = element_blank())
@IndrajeetPatil IndrajeetPatil added the Enhancement 💥 New feature or request label Mar 15, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Enhancement 💥 New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants