---
title: "Migrating from version 0.1.0"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Migrating from version 0.1.0}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7,
                      fig.height = 4.5)
library(BayesianQDM)
```

Version 1.0.0 of BayesianQDM is a redesign of version 0.1.0 and is not
backward compatible. In version 0.1.0, each combination of endpoint and
operation had its own function with up to about 50 arguments. In version
1.0.0, a study is described by small specification objects that are
combined into a design, and three functions work with any design. This
vignette shows how to translate code written for version 0.1.0 and lists
the changes in the results. The code for version 0.1.0 is shown but not run.

## Correspondence of the functions

| Version 0.1.0 | Version 1.0.0 |
|---|---|
| `pbayespostpred1bin()`, `pbayespostpred1cont()`, `pbayespostpred2bin()`, `pbayespostpred2cont()` | `qdm_decide()` with a design and observed data |
| `pbayesdecisionprob1bin()`, `pbayesdecisionprob1cont()`, `pbayesdecisionprob2bin()`, `pbayesdecisionprob2cont()` | `qdm_oc()` |
| `getgamma1bin()`, `getgamma1cont()`, `getgamma2bin()`, `getgamma2cont()` | `qdm_calibrate()` |
| `ptdiff_NI()`, `ptdiff_MC()`, `ptdiff_MM()` | `ptdiff()` with `method = "NI"`, `"MC"` or `"MM"` |
| `pbetadiff()`, `pbetabinomdiff()` | Same names, with the arguments ordered by group |
| `getjointbin()` | `cellprob_binary2()` |
| `rdirichlet()` | Same name |
| `allmultinom()` | Internal function |

## Correspondence of the arguments

| Version 0.1.0 | Version 1.0.0 |
|---|---|
| `prob = 'posterior'` with `theta_TV`, `theta_MAV`, `gamma_go`, `gamma_nogo` | `criterion_posterior(theta_tv, theta_mav, gamma_go, gamma_nogo)` |
| `prob = 'predictive'` with `theta_NULL`, `m_t`, `m_c` | `criterion_predictive(theta_null, m_t, m_c, gamma_go, gamma_nogo)` |
| `a_t`, `b_t`, `a_c`, `b_c` | `prior_beta(a, b)` for each group |
| `prior = 'vague'` | `prior_vague()` |
| `prior = 'N-Inv-Chisq'` with `mu0_*`, `kappa0_*`, `nu0_*`, `sigma0_*` | `prior_nix(mu0, kappa0, nu0, sigma0)` for each group |
| `CalcMethod` | `method` of `design_continuous()` and `design_continuous2()` |
| `design = 'controlled'` | `n_c` of at least 1 (binary endpoints), 2 (one continuous endpoint) or 3 (two continuous endpoints) |
| `design = 'external'` with `ne_*`, `ye_*` (or `bar_ye_*`, `se_*`) and `alpha0e_*` | `borrow(data_*(...), a0)` as `external_t` or `external_c` |
| `design = 'uncontrolled'` with `z` (binary) or `mu0_c` and `r` (continuous) | `n_c = 0` and `hypothetical_c = hypothetical(...)` |
| `pi_t`, `pi_c` and similar vectors of true parameters | A data frame of scenarios |
| `error_if_Miss`, `Gray_inc_Miss` | Removed; Miss decisions are reported in their own column |
| `col_go`, `col_nogo`, `col_gray` and `base_size` of the `plot()` methods | Same names, with `col_miss`, `linewidth`, `point_size`, `label_size` and `legend_position` where they apply; `base_size` is 11 by default instead of 28 |
| `title`, `xlab` and `ylab` of the `plot()` methods | `ggplot2::labs()` added to the plot |
| `which` of the `plot()` methods for two endpoints | One panel per decision by default; `overlay = TRUE` for `which = "overlay"` |

The meaning of `gamma_nogo` is unchanged: the NoGo criterion is
$\Pr(\theta \le \theta_{MAV} \mid D) \ge \gamma_{nogo}$.

## Posterior probability for observed data

Version 0.1.0:

```{r old-post, eval = FALSE}
pbayespostpred1bin(
  prob = 'posterior', design = 'controlled', theta0 = 0.05,
  n_t = 10, n_c = 10, y_t = 7, y_c = 3,
  a_t = 0.5, b_t = 0.5, a_c = 0.5, b_c = 0.5,
  m_t = NULL, m_c = NULL, z = NULL,
  ne_t = NULL, ne_c = NULL, ye_t = NULL, ye_c = NULL,
  alpha0e_t = NULL, alpha0e_c = NULL,
  lower.tail = FALSE
)
```

Version 1.0.0 computes the probability directly from the posterior
distributions $\textrm{Beta}(7.5, 3.5)$ and $\textrm{Beta}(3.5, 7.5)$, or as
the probability of the Go region of a design whose target value is 0.05:

```{r new-post}
pbetadiff(0.05, a_t = 7.5, b_t = 3.5, a_c = 3.5, b_c = 7.5,
          lower.tail = FALSE)

des <- design_binary(
  n_t = 10, n_c = 10,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.05, theta_mav = 0,
                                  gamma_go = 0.8, gamma_nogo = 0.8)
)
qdm_decide(des, data_t = data_binary(10, 7), data_c = data_binary(10, 3))
```

## Operating characteristics

Version 0.1.0:

```{r old-oc, eval = FALSE}
pbayesdecisionprob1bin(
  prob = 'posterior', design = 'controlled',
  theta_TV = 0.30, theta_MAV = 0.10, theta_NULL = NULL,
  gamma_go = 0.80, gamma_nogo = 0.20,
  pi_t = seq(0.15, 0.9, l = 10), pi_c = rep(0.15, 10),
  n_t = 10, n_c = 10,
  a_t = 0.5, b_t = 0.5, a_c = 0.5, b_c = 0.5,
  z = NULL, m_t = NULL, m_c = NULL,
  ne_t = NULL, ne_c = NULL, ye_t = NULL, ye_c = NULL,
  alpha0e_t = NULL, alpha0e_c = NULL
)
```

Version 1.0.0:

```{r new-oc}
des <- design_binary(
  n_t = 10, n_c = 10,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.30, theta_mav = 0.10,
                                  gamma_go = 0.80, gamma_nogo = 0.20)
)
oc <- qdm_oc(des, data.frame(pi_t = seq(0.15, 0.9, length.out = 10),
                             pi_c = 0.15))
oc
```

## Calibration of the thresholds

Version 0.1.0:

```{r old-cal, eval = FALSE}
getgamma1bin(
  prob = 'posterior', design = 'controlled',
  theta_TV = 0.30, theta_MAV = 0.10, theta_NULL = NULL,
  pi_t_go = 0.15, pi_c_go = 0.15, pi_t_nogo = 0.35, pi_c_nogo = 0.15,
  target_go = 0.05, target_nogo = 0.20,
  n_t = 12L, n_c = 12L,
  a_t = 0.5, b_t = 0.5, a_c = 0.5, b_c = 0.5,
  z = NULL, m_t = NULL, m_c = NULL,
  ne_t = NULL, ne_c = NULL, ye_t = NULL, ye_c = NULL,
  alpha0e_t = NULL, alpha0e_c = NULL
)
```

Version 1.0.0 (the thresholds of the design are replaced by the calibrated
ones):

```{r new-cal}
des12 <- design_binary(
  n_t = 12, n_c = 12,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.30, theta_mav = 0.10,
                                  gamma_go = 0.80, gamma_nogo = 0.20)
)
cal <- qdm_calibrate(des12,
                     scenario_go = data.frame(pi_t = 0.15, pi_c = 0.15),
                     scenario_nogo = data.frame(pi_t = 0.35, pi_c = 0.15),
                     target_go = 0.05, target_nogo = 0.20)
cal
```

Version 0.1.0 required the probabilities to be less than the targets;
version 1.0.0 requires them to be at most the targets.

## External data and hypothetical controls

External data given in version 0.1.0 by `ne_c = 20, ye_c = 5,
alpha0e_c = 0.5` are given in version 1.0.0 by
`external_c = borrow(data_binary(n = 20, y = 5), a0 = 0.5)`. For a
continuous endpoint, `ne_c`, `bar_ye_c`, `se_c` and `alpha0e_c` become
`borrow(data_continuous(n, mean, sd), a0)`.

The uncontrolled design of version 0.1.0 with `z` hypothetical responders
among `n_c` control subjects and control prior $\textrm{Beta}(a_c, b_c)$
corresponds to `n_c = 0`, `prior_c = prior_beta(a_c, b_c)` and
`hypothetical_c = hypothetical(data = data_binary(n_c, z))`; for example:

```{r hypothetical}
design_binary(
  n_t = 12, n_c = 0,
  prior_t = prior_beta(0.5, 0.5), prior_c = prior_beta(0.5, 0.5),
  criterion = criterion_posterior(theta_tv = 0.30, theta_mav = 0.10,
                                  gamma_go = 0.80, gamma_nogo = 0.20),
  hypothetical_c = hypothetical(data = data_binary(n = 12, y = 2))
)
```

For a continuous endpoint, `mu0_c` and `r` become
`hypothetical(mean = mu0_c, r = r)`.

## Changes in the results

Formulas and numerical methods that were wrong in version 0.1.0 have been
corrected, so some results differ.

- The posterior predictive distribution of the mean of $m$ future subjects
  of a continuous endpoint has the squared scale
  $\sigma_n^2 (1 / \kappa_n + 1 / m)$ (one endpoint) and the scale matrix
  $(1 / \kappa_n + 1 / m) \Lambda_n / (\nu_n - 1)$ (two endpoints).
  Version 0.1.0 treated the future subjects as independent draws from the
  predictive distribution of one subject, which understates the
  uncertainty.
- With the vague prior and external data for a continuous endpoint, the
  posterior distribution of the mean has $a_0 n_e + n - 1$ degrees of
  freedom, and its scale uses the same denominator (version 0.1.0 used
  $a_0 n_e + n$).
- For two binary endpoints, the predictive probabilities are computed
  exactly instead of by Monte Carlo simulation.
- For two continuous endpoints, the moment-matching approximation uses the
  real degrees of freedom (version 0.1.0 rounded them to an integer), and
  with Monte Carlo simulation each simulated study has its own draws
  (version 0.1.0 used the same draws for all simulated studies).
- Numerical integration for one continuous endpoint covers the whole real
  line (version 0.1.0 truncated the range).
- Probabilities are no longer set to 0 below `.Machine$double.eps^0.25`.
- Miss decisions (both criteria met) are reported in their own column with a
  warning, instead of an error or being counted as Gray.
- `qdm_decide()`, `qdm_oc()`, `qdm_calibrate()` and `qdm_boundary()` have a
  `seed` argument and restore the state of the random number generator when
  a seed is given.

Version 1.0.0 also has features without a counterpart in version 0.1.0: a
fixed control (`fixed_c` of the design functions) for single-arm studies
compared with a known value, smaller effects as favorable (`direction`
of the criterion functions), one time-to-event endpoint evaluated by the
milestone survival or the hazard ratio (`design_tte()`, see
`vignette("time-to-event")`) and decision boundaries (`qdm_boundary()`).
`NEWS.md` lists all changes.
