---
title: "Choosing the Right Demand Model"
author: "Brent Kaplan"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Choosing the Right Demand Model}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  echo = TRUE,
  collapse = TRUE,
  comment = "#>",
  dev = "png",
  dpi = 144,
  fig.width = 7,
  fig.height = 5,
  warning = FALSE,
  message = FALSE
)

library(beezdemand)
library(dplyr)
data(apt)
```

# Introduction

The `beezdemand` package provides multiple approaches for fitting behavioral
economic demand curves. This guide helps you choose the right modeling approach
for your data and research questions.

## When to Use Demand Analysis

Demand analysis is appropriate when you want to:
- Quantify the value of a reinforcer (e.g., drugs, food, activities)
- Compare demand elasticity across conditions or groups
- Estimate key parameters like intensity (Q0), elasticity (alpha), and breakpoint
- Compute derived metrics like Pmax (price at maximum expenditure) and Omax (maximum expenditure)

## Quick Decision Guide

| Your Situation | Recommended Approach | Function |
|----------------|---------------------|----------|
| Individual curves, quick exploration | Fixed-effects NLS | `fit_demand_fixed()` |
| Group comparisons, repeated measures | Mixed-effects | `fit_demand_mixed()` |
| Many zeros, two-part modeling | Hurdle model | `fit_demand_hurdle()` |
| Cross-commodity substitution | Cross-price models | `fit_cp_*()` |

---

# Data Quality First

Before fitting any model, always check your data for systematic responding.

```{r check-systematic}
# Check for systematic demand
systematic_check <- check_systematic_demand(apt)
head(systematic_check$results)

# Filter to systematic data only (those that pass all criteria)
systematic_ids <- systematic_check$results |>
  filter(systematic) |>
  dplyr::pull(id)

apt_clean <- apt |>
  filter(as.character(id) %in% systematic_ids)

cat("Systematic participants:", n_distinct(apt_clean$id),
    "of", n_distinct(apt$id), "\n")
```

The `check_systematic_demand()` function applies criteria from Stein et al. (2015)
to identify nonsystematic responding patterns including:

- **Trend (DeltaQ)**: Consumption should decrease as price increases
- **Bounce**: Limited price-to-price increases in consumption
- **Reversals**: No consumption after sustained zeros

---

# Tier 1: Fixed-Effects NLS

## When to Use

Use `fit_demand_fixed()` when you want:

- Individual demand curves for each participant
- Quick exploration of your data
- Compatibility with traditional analysis approaches
- Per-subject parameter estimates without pooling information

## Complete Example

```{r fixed-example}
# Fit individual demand curves using the Hursh & Silberberg equation
fit_fixed <- fit_demand_fixed(
  data = apt,
  equation = "hs",
  k = 2
)

# Print summary
print(fit_fixed)

# Get tidy coefficient table
tidy(fit_fixed) |> head()

# Get model-level statistics
glance(fit_fixed)
```

```{r fixed-plot, fig.cap="Individual demand curves for two example participants."}
# Plot individual curves
plot(fit_fixed, type = "individual", ids = c("19", "51"))
```

```{r fixed-diagnostics}
# Basic diagnostics
check_demand_model(fit_fixed)
```

---

# Tier 2: Mixed-Effects Models

## When to Use

Use `fit_demand_mixed()` when you want:

- Group comparisons with statistical inference
- Random effects to account for individual variability
- Post-hoc comparisons between conditions
- Estimated marginal means for factor levels

## The LL4 Transformation

For the mixed-effects approach with the `zben` equation form, transform your
consumption data using the LL4 (log-log with 4-parameter adjustment):

```{r ll4-transform, eval=FALSE}
# Transform consumption using LL4
apt_ll4 <- apt |>
  dplyr::mutate(y_ll4 = ll4(y))

# View the transformation
apt_ll4 |>
  dplyr::filter(id == 19) |>
  dplyr::select(id, x, y, y_ll4)
```

## Complete Example

```{r mixed-example, eval=FALSE}
# Fit mixed-effects model
fit_mixed <- fit_demand_mixed(
  data = apt_ll4,
  y_var = "y_ll4",
  x_var = "x",
  id_var = "id",
  equation_form = "zben"
)

# Print summary
print(fit_mixed)
summary(fit_mixed)

# Basic diagnostics
check_demand_model(fit_mixed)
plot_residuals(fit_mixed)$fitted
```

## Post-Hoc Analysis with emmeans

For experimental designs with factors, you can use `emmeans` for post-hoc comparisons:

```{r emmeans-example, eval=FALSE}
# For a model with factors (example with ko dataset):
data(ko)

# Prepare data with LL4 transformation
# (Note: the ko dataset already includes a y_ll4 column, but we
# recreate it here to demonstrate the transformation workflow)
ko_ll4 <- ko |>
  dplyr::mutate(y_ll4 = ll4(y))

fit <- fit_demand_mixed(
  data = ko_ll4,
  y_var = "y_ll4",
  x_var = "x",
  id_var = "monkey",
  factors = c("drug", "dose"),
  equation_form = "zben"
)

# Get estimated marginal means for Q0 and alpha across drug levels
emms <- get_demand_param_emms(fit, factors_in_emm = "drug", include_ev = TRUE)

# Pairwise comparisons of drug conditions
comps <- get_demand_comparisons(fit, compare_specs = ~drug, contrast_type = "pairwise")
```

---

# Tier 3: Hurdle Models

## When to Use

Use `fit_demand_hurdle()` when you have:

- Substantial zero consumption values (>10-15% zeros)
- Need for two-part modeling (zeros vs. positive consumption)
- Interest in both participation and consumption intensity
- TMB backend for fast, stable estimation

## Understanding the Two-Part Structure

The hurdle model separates:

1. **Part I**: Probability of zero consumption (logistic regression)
2. **Part II**: Log-consumption given positive response (nonlinear mixed effects)

## Complete Example

```{r hurdle-example, eval=FALSE}
# Fit hurdle model with 3 random effects
fit_hurdle <- fit_demand_hurdle(
  data = apt,
  y_var = "y",
  x_var = "x",
  id_var = "id",
  random_effects = c("zeros", "q0", "alpha")
)

# Summary
summary(fit_hurdle)

# Population demand curve
plot(fit_hurdle, type = "demand")

# Probability of zero consumption
plot(fit_hurdle, type = "probability")

# Basic diagnostics
check_demand_model(fit_hurdle)
plot_residuals(fit_hurdle)$fitted
plot_qq(fit_hurdle)
```

## Comparing Hurdle Models

Compare nested models using likelihood ratio tests:

```{r hurdle-compare, eval=FALSE}
# Fit full model (3 random effects)
fit_hurdle3 <- fit_demand_hurdle(
  data = apt,
  y_var = "y",
  x_var = "x",
  id_var = "id",
  random_effects = c("zeros", "q0", "alpha")
)

# Fit simplified model (2 random effects)
fit_hurdle2 <- fit_demand_hurdle(
  data = apt,
  y_var = "y",
  x_var = "x",
  id_var = "id",
  random_effects = c("zeros", "q0")  # No alpha random effect
)

# Compare models
compare_hurdle_models(fit_hurdle3, fit_hurdle2)

# Unified model comparison (AIC/BIC + LRT when appropriate)
compare_models(fit_hurdle3, fit_hurdle2)
```

---

# Choosing an Equation

The `equation` argument determines the functional form of the demand curve.
Each equation has trade-offs in terms of flexibility, zero handling, and
comparability across studies.

| Equation | Function | Handles Zeros | k Required | Best For |
|----------|----------|:-------------:|:----------:|----------|
| `"hs"` | Hursh & Silberberg (2008) | No | Yes | Traditional analyses, compatibility with older literature |
| `"koff"` | Koffarnus et al. (2015) | No | Yes | Modified exponential, widely used in applied research |
| `"simplified"` | Rzeszutek et al. (2025) | Yes | No | Modern analyses; avoids k-dependency and zero issues |

**Recommendations:**

- For **new analyses**, consider using `"simplified"` (also called SND) as it
  handles zeros natively and does not require specifying `k`, making results
  more comparable across studies.
- For **replication or comparability** with existing literature, use `"hs"` or
  `"koff"` with the same `k` specification as the original study.
- When using `"hs"` or `"koff"`, zeros in consumption data are incompatible
  with the log transformation and will be dropped with a warning.

---

# Choosing Parameters

## The k Parameter

The scaling constant `k` controls the asymptotic range of the demand curve:

- **`k = 2`**: Good default for most purchase task data
- **`k = "ind"`**: Calculate k individually for each participant
- **`k = "fit"`**: Estimate k as a free parameter
- **`k = "share"`**: Fit a single k shared across all participants

```{r k-example, eval=FALSE}
# Different k specifications
fit_k2 <- fit_demand_fixed(apt, k = 2)          # Fixed at 2
fit_kind <- fit_demand_fixed(apt, k = "ind")    # Individual
fit_kfit <- fit_demand_fixed(apt, k = "fit")    # Free parameter
fit_kshare <- fit_demand_fixed(apt, k = "share") # Shared across participants
```

## Interpreting Key Parameters

| Parameter | Interpretation | Typical Range |
|-----------|---------------|---------------|
| Q0 (Intensity) | Consumption at zero price | Dataset-dependent |
| alpha (Elasticity) | Rate of consumption decline | 0.0001 - 0.1 |
| Pmax | Price at maximum expenditure | Dataset-dependent |
| Omax | Maximum expenditure | Dataset-dependent |
| Breakpoint | First price with zero consumption | Dataset-dependent |

---

# Troubleshooting FAQ

## Model Convergence Issues

**Problem**: Model fails to converge or produces unreasonable estimates.

**Solutions**:

1. Check data quality with `check_systematic_demand()`
2. Try different starting values
3. Use a simpler model (fewer random effects)
4. Ensure sufficient data per participant

## Zero Handling

**Problem**: Many zeros in consumption data.

**Solutions**:

1. Use `fit_demand_hurdle()` which explicitly models zeros
2. For fixed-effects: zeros are automatically excluded for log-transformed equations
3. Consider data quality: excessive zeros may indicate nonsystematic responding

## Parameter Comparison Across Models

**Problem**: Comparing alpha values between different model types.

**Solution**: Be aware of parameterization differences:

- Hurdle models estimate on natural-log scale internally
- Use `tidy(fit, report_space = "log10")` for comparable output
- The transformation is: `log10(alpha) = log(alpha) / log(10)`

---

# Summary

| Approach | Best For | Key Features | Handles Zeros |
|----------|----------|--------------|---------------|
| `fit_demand_fixed()` | Individual curves, quick analysis | Simple, per-subject estimates | Excludes |
| `fit_demand_mixed()` | Group comparisons, repeated measures | Random effects, emmeans integration | LL4 transform |
| `fit_demand_hurdle()` | Data with many zeros | Two-part model, TMB backend | Explicitly models |

## Next Steps

- **Getting Started**: See `vignette("beezdemand")` for basic usage
- **Fixed-Effect Models**: See `vignette("fixed-demand")` for individual demand curve fitting
- **Group Comparisons**: See `vignette("group-comparisons")` for extra sum-of-squares F-test
- **Mixed Models**: See `vignette("mixed-demand")` for mixed-effects examples
- **Advanced Mixed Models**: See `vignette("mixed-demand-advanced")` for factors, EMMs, covariates
- **Hurdle Models**: See `vignette("hurdle-demand-models")` for hurdle model details
- **Cross-Price**: See `vignette("cross-price-models")` for substitution analyses
- **Migration Guide**: See `vignette("migration-guide")` for migrating from `FitCurves()`

---

# References

- Hursh, S. R., & Silberberg, A. (2008). Economic demand and essential value. *Psychological Review, 115*(1), 186-198.
- Koffarnus, M. N., Franck, C. T., Stein, J. S., & Bickel, W. K. (2015). A modified exponential behavioral economic demand model to better describe consumption data. *Experimental and Clinical Psychopharmacology, 23*(6), 504-512.
- Stein, J. S., Koffarnus, M. N., Snider, S. E., Quisenberry, A. J., & Bickel, W. K. (2015). Identification and management of nonsystematic purchase task data: Toward best practice. *Experimental and Clinical Psychopharmacology, 23*(5), 377-386.
- Kaplan, B. A., Franck, C. T., McKee, K., Gilroy, S. P., & Koffarnus, M. N. (2021). Applying mixed-effects modeling to behavioral economic demand: An introduction. *Perspectives on Behavior Science, 44*(2), 333-358.
- Rzeszutek, M. J., Regnier, S. D., Franck, C. T., & Koffarnus, M. N. (2025). Overviewing the exponential model of demand and introducing a simplification that solves issues of span, scale, and zeros. *Experimental and Clinical Psychopharmacology*.
