Skip to contents

Computes willingness-to-pay (WTP) ratios with delta-method standard errors from a fitted choice model. For an attribute coefficient \(\theta_k\) and a price coefficient \(\theta_p\), the WTP is $$WTP_k = -\theta_k / \theta_p,$$ the marginal rate of substitution between the attribute and price. Standard errors use the delta method with analytic gradients \(\partial g/\partial \theta_k = -1/\theta_p\) and \(\partial g/\partial \theta_p = \theta_k/\theta_p^2\), applied to the corresponding 2x2 block of vcov(object).

Usage

# S3 method for class 'choicer_hb'
wtp(object, price_var, attr_vars = NULL, level = 0.95, ...)

wtp(object, price_var, attr_vars = NULL, level = 0.95, ...)

# S3 method for class 'choicer_fit'
wtp(object, price_var, attr_vars = NULL, level = 0.95, ...)

# S3 method for class 'choicer_mxl'
wtp(object, price_var, attr_vars = NULL, level = 0.95, ...)

Arguments

object

A fitted model object (choicer_mnl, choicer_mxl, or choicer_nl).

price_var

Name of the price variable. Must be a fixed-coefficient variable (a column of the design matrix X).

attr_vars

Character vector of attributes to report. Defaults to all fixed-coefficient variables other than price_var (plus, for mixed logit with rc_mean = TRUE, all random coefficients). ASC names (e.g. "ASC_2") may also be supplied; the WTP of an ASC is \(-ASC_j / \theta_p\).

level

Confidence level for the normal-approximation interval \(Estimate \pm z_{1-(1-level)/2} \times SE\). Default 0.95.

...

Additional arguments passed to methods.

Value

A data.frame of class choicer_wtp with one row per attribute and columns Estimate, Std_Error, z_value, CI_lower, CI_upper. Attributes price_var and level record the inputs; median_rows lists rows that are median (rather than mean) WTP. Standard errors are NA when the variance-covariance matrix is unavailable.

Details

For mixed logit models, random coefficients are included via their estimated location parameters. The package's log-normal random coefficient is the shifted log-normal \(\beta_k = \exp(\mu_k) + \exp((L\eta)_k)\) (see run_mxlogit()), so:

  • Normal random coefficient \(k\) (rc_mean = TRUE): mean WTP \(-\mu_k / \theta_p\), labeled Mu_x.

  • Log-normal random coefficient \(k\) (rc_mean = TRUE): median WTP \(-(\exp(\mu_k) + 1) / \theta_p\), since the median of \(\exp((L\eta)_k)\) is 1. (The mean, \(\exp(\mu_k) + \exp(\sigma_k^2/2)\), is highly sensitive to the estimated variance; the median is the more robust summary.) These rows are labeled by the attribute name and flagged as medians when printed.

  • Log-normal random coefficient with rc_mean = FALSE: \(\beta_k = \exp((L\eta)_k)\) has median 1, so the median WTP is \(-1/\theta_p\) with uncertainty driven solely by \(\theta_p\).

Normal random coefficients with rc_mean = FALSE have mean 0 by construction and are excluded from the table.

The price variable must have a fixed coefficient. A random price coefficient is rejected: the ratio of two random coefficients generally has no finite moments (the denominator has positive density at 0), so mean or median WTP computed from location parameters would be meaningless. In choicer, use a fixed price coefficient. WTP-space estimation is not currently implemented; it is an alternative specification available in other software rather than an option supplied by this function.

Methods (by class)

  • wtp(choicer_hb): Posterior willingness-to-pay for hierarchical Bayes fits: the per-draw ratio of population-mean utility coefficients, \(-\bar\gamma_{attr} / \bar\gamma_{price}\) (for log-normal coordinates \(\bar\gamma = \exp(b + W_{kk}/2)\)). Ratio posteriors are heavy-tailed, so the point estimate is the posterior median with equal-tailed quantile intervals — never a posterior mean or a delta-method SE. A warning is raised when the price coefficient's sign is not resolved by the posterior. If the price variable was flagged as endogenous-without-a-control-function at prep time, WTP inherits that caveat (see cf_residual_col in prepare_hmnl_data()).

Examples

# \donttest{
library(data.table)
sim <- simulate_mnl_data(N = 1000, J = 4, beta = c(0.8, -0.6), seed = 123,
                         outside_option = FALSE, vary_choice_set = FALSE)
fit <- run_mnlogit(sim$data, "id", "alt", "choice", c("x1", "x2"))
#> Optimization run time 0h:0m:0.01s
# treat x2 as the price variable
wtp(fit, price_var = "x2")
#> Willingness to pay (WTP), price variable: 'x2' (95% CI)
#>    Estimate Std_Error z_value CI_lower CI_upper
#> x1     1.59    0.2336   6.809    1.132    2.048
wtp(fit, price_var = "x2", attr_vars = c("x1", "ASC_2"), level = 0.90)
#> Willingness to pay (WTP), price variable: 'x2' (90% CI)
#>       Estimate Std_Error z_value CI_lower CI_upper
#> x1       1.590    0.2336   6.809    1.206    1.974
#> ASC_2   -2.027    0.3157  -6.420   -2.546   -1.507
# }