Skip to contents

A league table puts every pairwise estimate of a network meta-analysis in one grid. Each number in it blends direct evidence, from trials that compare the pair head to head, with indirect evidence carried through the rest of the network, and how much of each goes into a cell matters for how far it can be trusted. ggleague() shows that split for every cell, next to a ranking of the treatments, and opens the direct trials on click.

A first league table

The network is the one drawn by ggnma(): five randomized trials of treatments for plaque psoriasis, analyzed for PASI 75 response with netmeta.

pw <- meta::pairwise(
  treat = treatment, event = pasi75_r, n = pasi75_n,
  studlab = study, data = psoriasis_nma, sm = "OR"
)
nma <- netmeta::netmeta(pw, common = FALSE)

ggleague(
  nma, psoriasis_nma, study, treatment,
  small_values = "undesirable",
  title = "PASI 75 response"
)

Hover over a cell for its network, direct and indirect estimates and the share of the network estimate that comes from direct trials. Click it to compare the direct trials arm by arm. Hover over a treatment, on the diagonal or in the ranking, to light its row and column.

Reading the table

The layout follows netmeta::netleague(). Each cell compares the treatment that comes first in the table with the one that comes second:

  • below the diagonal, the network estimate;
  • above the diagonal, the direct estimate, or “no direct trials” when no trial compares the pair.

Treatments are ordered by P-score, best first, so most cells favor the first treatment. Cells are shaded by the size of the effect, in one color when it favors the first treatment and another when it favors the second, and faded when the confidence interval includes no difference.

Which way is better

small_values says whether small values of the effect are desirable, as for mortality, or undesirable, as for a response. It sets which treatment a cell favors and the direction of the ranking, so it has to be right for the outcome. It defaults to the setting stored in the netmeta object, which netmeta sets to “desirable” unless told otherwise; for a response such as PASI 75 that is the wrong way round, and the table above passes small_values = "undesirable".

Click panels

With data, study and treatment, the arm level data, a click on a cell opens the arms of every direct trial side by side, in the same table the network plot uses, with every other column of the data as a row. Without them, the panel lists each direct trial’s own estimate:

ggleague(nma, small_values = "undesirable", ranking = FALSE)

Where each estimate comes from

A network estimate draws on every direct comparison connected to it, not only the trials of its own pair. contributions = TRUE computes, with netmeta::netcontrib(), the share of each network estimate that flows through each direct comparison. Computing it takes a few seconds for a large network, so it can also be given as the object that function returns, to share with ggnma():

flow <- netmeta::netcontrib(nma)
ggleague(nma, psoriasis_nma, study, treatment, small_values = "undesirable",
         contributions = flow)

Hover over or tap any estimate: the direct comparisons it draws on are outlined above the diagonal with their shares, and a sentence under the table names the largest. Its panel gains a table of every contribution. The shares say where the information comes from, not how trustworthy it is.

Options

argument effect
pooled "random" or "common"; defaults to the random effects model
order the order of the treatments; defaults to the ranking
ranking draw the P-score ranking beside the table
caption replaces the default note on which estimate sits where

Like the other graphs, the table prints as a widget, and graph_plot(), graph_widget() and graph_save() give it as a ggplot, an htmlwidget or a file.