---
title: "Responder analysis from a fitted meta-analysis"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Responder analysis from a fitted meta-analysis}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
library(respondeR)
```

You often already have a continuous meta-analysis fitted and saved in an R
object. respondeR can read that object directly and express it as responder
risks, so you do not have to rebuild the arm-level data frame by hand. It reads
the saved object with base R, so the package that produced it (for example
*meta* or *metafor*) does not even need to be attached.

There are two situations, handled automatically:

* the object **carries the per-arm summaries** (a `metacont` from *meta*): it
  is converted to the data-frame form and analyzed with the full method menu;
* the object **carries only the pooled relative effect** (a *metafor* `rma`
  fit): it is converted with `responder_from_effect()`, and you supply a baseline
  control responder risk (by name: `baseline = `).

## From a `meta` (metacont) object

A `metacont` object stores both arms, so respondeR can run the complete analysis.
You would normally create it like this:

```{r, eval = FALSE}
library(meta)
fit <- metacont(
  n.e = n_e, mean.e = change_e, sd.e = sd_e,
  n.c = n_c, mean.c = change_c, sd.c = sd_c,
  studlab = study, data = sample_responder_data
)
responder_analysis(fit, mid = 1)
```

A `metacont` object is, in the end, a list with the per-arm fields respondeR
reads (`mean.e`, `sd.e`, `n.e`, `mean.c`, `sd.c`, `n.c`, `studlab`). To keep this
vignette runnable without *meta* installed, here is the same object built by
hand:

```{r}
d <- sample_responder_data
fit_meta <- structure(
  list(
    studlab = d$study,
    n.e = d$n_e, mean.e = d$change_e, sd.e = d$sd_e,
    n.c = d$n_c, mean.c = d$change_c, sd.c = d$sd_c,
    sm = "MD"
  ),
  class = c("metacont", "meta")
)

responder_analysis(fit_meta, mid = 1)[, c("method", "p_e", "p_c", "rd", "rr", "or")]
```

That is identical to calling `responder_analysis()` on the data frame; all the
usual arguments (`direction`, `method`, `pooling`, `control`, ...) pass straight
through. The fitted object's own choices carry over unless you override them:
studies excluded from the fit (its `exclude` argument) are dropped, a random-effects
fit (`common = FALSE, random = TRUE`) sets `pooling = "random"`, its `method.tau`
(DL or REML) sets `tau_method`, and a Hartung-Knapp fit sets `ci_method = "hksj"`.
Repeated study labels (the comparisons of a multi-arm trial) become a `trial`
column, so a shared control arm is split rather than double counted. If you only
want the extracted data frame, use `as_responder_data()`.

## From a `metafor` `rma` object

An `rma` fit keeps the pooled relative effect, not the arms. respondeR reads the
estimate, its standard error, its confidence interval (so a Knapp-Hartung `t`
interval and the fit's confidence level are kept) and the effect measure, then
converts. Because the arms are gone, you must tell it the **baseline** control
responder risk (as a probability, or as a control mean and SD), by name.
Meta-regressions, models without an intercept and raw-mean measures are
rejected.

```{r, eval = requireNamespace("metafor", quietly = TRUE)}
library(metafor)
es <- escalc(
  measure = "SMD", m1i = change_e, sd1i = sd_e, n1i = n_e,
  m2i = change_c, sd2i = sd_c, n2i = n_c, data = d
)
fit_rma <- rma(yi, vi, data = es)

# A standardized mean difference, against a 22% control responder rate:
responder_analysis(fit_rma, baseline = 0.22)[, c("method", "p_e", "p_c", "rd", "or")]
```

The effect is read as experimental minus control and oriented by `direction`.
For pain, where a reduction is the response, a negative SMD is a benefit:

```{r, eval = requireNamespace("metafor", quietly = TRUE)}
es_vas <- escalc(
  measure = "SMD", m1i = change_e, sd1i = sd_e, n1i = n_e,
  m2i = change_c, sd2i = sd_c, n2i = n_c, data = vas_pain
)
fit_vas <- rma(yi, vi, data = es_vas, test = "knha")
responder_analysis(fit_vas, baseline = 0.4, direction = "lower")
```

For a mean-difference model you also pass a reference within-arm SD (`sd_ref`),
the scale on which the threshold lives, and you can give the baseline as a
control mean and SD:

```{r, eval = requireNamespace("metafor", quietly = TRUE)}
es_md <- escalc(
  measure = "MD", m1i = change_e, sd1i = sd_e, n1i = n_e,
  m2i = change_c, sd2i = sd_c, n2i = n_c, data = d
)
fit_md <- rma(yi, vi, data = es_md)

responder_analysis(fit_md, baseline = list(mean = 0, sd = 1.3),
                   mid = 1, sd_ref = 1.3)[, c("method", "p_e", "p_c", "rd")]
```

## From a bare estimate

If all you have is a number from a paper (a pooled SMD or MD with its SE), call
the engine directly:

```{r}
# Pooled SMD of 0.5 (SE 0.1) vs a 25% control responder rate:
responder_from_effect(0.5, se = 0.1, measure = "SMD", baseline = 0.25)[,
  c("method", "p_e", "p_c", "rd", "or")]
```

## How the conversion works, and what it assumes

For a **standardized mean difference** `g`, respondeR maps it to an odds ratio
through the logistic distribution, `lnOR = (pi / sqrt(3)) g` (Hasselblad and
Hedges, 1995; Chinn, 2000; Anzures-Cabrera, Sarpatwari & Higgins, 2011), then
combines that odds ratio with the control responder proportion `p_c` to recover
the experimental proportion and the risk difference, risk ratio, odds ratio and
NNT.

For a **mean difference** `MD`, respondeR shifts the control responder
probability along the Normal cut-point: `p_e = Phi(Phi^-1(p_c) + MD / sigma)`,
where `sigma` is the reference within-arm SD (`sd_ref`). This conversion assumes
Normal change scores. Both risks depend on the same baseline, so when the
baseline is estimated (a mean, SD and `n`) its uncertainty is propagated jointly
with that of the effect.

Two assumptions matter. First, the **baseline** is yours to choose: a defensible
control responder rate, taken from a representative control arm or an external
source, much as a GRADE summary-of-findings table fixes one baseline risk. A
fixed baseline probability gives intervals conditional on it.
Second, the **mean-difference path needs a reference SD**; pick the typical
within-arm SD on the outcome scale, and report it.

## Coming next

Support for network meta-analysis objects (`netmeta`) and Bayesian network
meta-analysis / multilevel network meta-regression (`multinma`) is planned for a
later release: each comparison or posterior draw will be converted to responder
risks against a chosen baseline.

## References

Thorlund, K., Walter, S. D., Johnston, B. C., Furukawa, T. A., & Guyatt, G. H.
(2011). Pooling health-related quality of life outcomes in meta-analysis.
*Research Synthesis Methods*, 2(3), 188 to 203. doi:10.1002/jrsm.46

Anzures-Cabrera, J., Sarpatwari, A., & Higgins, J. P. T. (2011). Expressing
findings from meta-analyses of continuous outcomes in terms of risks.
*Statistics in Medicine*, 30(25), 2967 to 2985. doi:10.1002/sim.4298

Chinn, S. (2000). A simple method for converting an odds ratio to effect size for
use in meta-analysis. *Statistics in Medicine*, 19(22), 3127 to 3131.

Hasselblad, V., & Hedges, L. V. (1995). Meta-analysis of screening and
diagnostic tests. *Psychological Bulletin*, 117(1), 167 to 178.
