---
title: "Discounting from trial-level choices"
author: "Brent Kaplan"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Discounting from trial-level choices}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
has_tmb <- requireNamespace("TMB", quietly = TRUE)
knitr::opts_chunk$set(
  collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4.2,
  eval = has_tmb
)
set.seed(1)
library(beezdiscounting)
```

Most discounting analyses start from indifference points (the amount that makes a
delayed reward feel equal to an immediate one). Many tasks, though, record the raw
decisions instead: for each offer, did the person take the smaller-sooner (SS)
reward or wait for the larger-later (LL) one? `fit_dd_choice()` models those
trial-level choices directly, without reducing them to indifference points first.

It fits two kinds of model:

- a **structural** model that assumes a discount function and estimates the
  discount rate `k` from the choices, and
- a **descriptive** model (Young, 2018) that predicts the choice from its
  features (the amount ratio and the delay) without committing to a discount
  function.

This vignette is a tour of both. It pairs with `vignette("delay-discounting-basics")`
(the indifference-point workflow), `vignette("dd-group-comparisons")` (contrasting
`k` across groups), and `vignette("bayesian-discounting")` (the brms versions).
TMB must be installed for the models to run.

## Data format

Choice data are long, one row per trial, with five columns: a subject `id`, the
smaller-sooner amount `ss_amount`, the larger-later amount `ll_amount`, the
`delay` to the larger reward, and the `choice` (`0` = chose SS, `1` = chose LL).
`simulate_dd_choice()` generates data in exactly that layout, which makes it
convenient for a reproducible walk-through; bring your own frame with the same
columns for a real analysis.

```{r sim}
ch <- simulate_dd_choice(n_subjects = 30, log_k_pop = log(0.02), seed = 1)
head(ch)
```

## Structural model

`fit_dd_choice(mode = "structural")` is the model to use when you want a
discount rate. It compares the discounted value of the larger-later reward against
the smaller-sooner reward on every trial and estimates `log k` directly:

`logit P(LL) = b0 + gamma ((ll / ss) D(k, delay) - 1)`,

where `D(k, delay)` is the discount function (Mazur's hyperbola by default),
`gamma` is the choice sensitivity (how sharply choices follow value), and the
optional `b0` is a side-independent choice bias (off by default). The comparison
is scale-invariant, so only the ratio of the rewards matters.

```{r structural}
fit_s <- fit_dd_choice(ch, mode = "structural", verbose = 0)
summary(fit_s)
```

The fixed-effect `k` is on the natural scale, alongside `gamma`. A subject random
intercept on `log k` lets each person have their own rate, pooled toward the group.
`tidy()` returns the same information as a data frame:

```{r structural-tidy}
tidy(fit_s)
```

Because the model estimates a discount rate, it implies a discounting curve, the
same object the indifference-point models produce. `plot()` draws that implied
curve, `D(k, delay) = 1 / (1 + k * delay)`, from the fitted `k`:

```{r curve}
plot(fit_s, type = "population")
```

## Descriptive model (Young, 2018)

`fit_dd_choice(mode = "descriptive")` takes a different stance. Rather than assume
a discount function, it predicts the choice with a logistic mixed model whose
fixed effects are the log amount ratio, `log(ll / ss)`, and the log delay,
`log(delay + 1)`, with subject random slopes on both. The coefficients (`theta`)
are sensitivities on the logit scale, not a discount rate.

```{r descriptive}
fit_d <- fit_dd_choice(ch, mode = "descriptive", verbose = 0)
summary(fit_d)
```

Interpret the sensitivities by their sign. A positive sensitivity on `log(ll / ss)` means
choices move toward the larger-later reward as it grows relative to the
smaller-sooner one; a negative sensitivity on `log(delay + 1)` means a longer wait
pushes choices back toward smaller-sooner. The descriptive model does not return a
`k`, so it cannot draw a discounting curve, but it does not depend on the discount
function being correctly specified either. (The random-slope covariance is weakly
identified in this small fixed-item example, so its correlation can sit at the
boundary; read the fixed sensitivities first.)

Use the structural model when you want an interpretable discount rate that is
comparable across tasks and groups under a shared discount function. Reach for the
descriptive model when you want a function-free summary of what drives the choices,
or as a check on whether the structural form is doing the data justice.

## S3 methods

Both fits carry the broom and base S3 surface. `glance()` gives a one-row model
summary; `coef()` returns the raw parameter vector on the optimizer's log scale
(`summary()` and `tidy()` report `k` and `gamma` back-transformed to the natural
scale); and `predict()` adds a `.prob` column with the per-trial probability of
choosing larger-later:

```{r methods}
glance(fit_s)

head(predict(fit_s))
```

`tidy()`, `summary()`, `print()`, `logLik()`, `AIC()`, and `BIC()` work as well.

## From the 27-item MCQ to choices

The 27-item Monetary Choice Questionnaire is itself a set of SS-vs-LL choices, so
its responses fit this model after reshaping. `mcq27_to_choice()` turns the
long-form questionnaire (`subjectid` / `questionid` / `response`) into the
per-trial frame, using the Kirby, Petry, and Bickel (1999) item design:

```{r mcq}
mc <- mcq27_to_choice(mcq27)
head(mc)

fit_mcq <- fit_dd_choice(mc, mode = "structural", verbose = 0)
tidy(fit_mcq)
```

This targets the same Mazur `k` construct and Kirby item design that
`score_mcq27()` uses, but estimates it with a mixed-effects likelihood model
rather than the per-subject Kirby threshold scorer (see
`vignette("mcq27-scoring")` for the classic scorer).

## Indifference points and choices agree

The structural choice model and the indifference-point models target the same
discount rate, so they should land in the same place when the data come from the
same process. Simulating both from a common `log k` and fitting each confirms it:

```{r tieout}
lk <- log(0.02)

ip <- simulate_dd_ip(
  n_subjects = 30, log_k_pop = lk,
  family = "sltb", equation = "mazur", seed = 3
)
fit_ip <- fit_dd_tmb(ip, equation = "mazur", family = "sltb", random_effects = k ~ 1)

choices <- simulate_dd_choice(n_subjects = 30, log_k_pop = lk, seed = 3)
fit_ch <- fit_dd_choice(choices, mode = "structural", verbose = 0)

c(
  truth = exp(lk),
  indifference_point = tidy(fit_ip)$estimate[tidy(fit_ip)$term == "k:(Intercept)"][1],
  choice = tidy(fit_ch)$estimate[tidy(fit_ch)$term == "k:(Intercept)"][1]
)
```

The two estimates are compatible in this controlled simulation, recovering the
same rate from different data; the package's IP-vs-choice tie-out test checks that
this agreement holds within tolerance.

## Where to go next

- To compare `k` between groups (treatment vs. control, and the like), add
  `factors =` and use `get_dd_param_emms()` / `get_dd_comparisons()`, covered in
  `vignette("dd-group-comparisons")`.
- For a Bayesian fit of the structural choice model, `fit_dd_choice_brms()` takes
  the same data and design; see `vignette("bayesian-discounting")`.

## References

- Kirby, K. N., Petry, N. M., & Bickel, W. K. (1999). Heroin addicts have higher
  discount rates for delayed rewards than non-drug-using controls. *Journal of
  Experimental Psychology: General, 128*(1), 78-87.
- Mazur, J. E. (1987). An adjusting procedure for studying delayed reinforcement.
  In M. L. Commons, J. E. Mazur, J. A. Nevin, & H. Rachlin (Eds.), *The effect of
  delay and of intervening events on reinforcement value* (pp. 55-73). Lawrence
  Erlbaum Associates.
- Young, M. E. (2018). Discounting: A practical guide to multilevel analysis of
  choice data. *Journal of the Experimental Analysis of Behavior, 109*(2),
  293-312.
