Methods
How the analyzer turns respondent-level hypothetical purchase task (HPT) data into aggregate demand curves, and exactly how the model is fitted.
Data & aggregation
The analyzer accepts wide-format survey data: one row per respondent, one column per price point. Depending on the response format you select, it aggregates each price column into a single demand value:
- Yes/no purchase responses — the percentage of respondents who would purchase at that price (respondents with missing or uninterpretable cells are excluded from that price's denominator).
- Quantities — the mean number of units respondents report they would purchase at that price.
If a grouping column is selected, the same aggregation runs separately for each group in addition to the full sample ("All"), and each series gets its own fitted curve.
The demand model
Aggregated demand is fitted with the exponentiated demand model of Koffarnus, Franck, Stein & Bickel (2015), where Q is predicted demand (% purchasing, or mean units) at price P:
Model parameters
- Q0
- Demand intensity — the level of demand when the product is free or nearly free.
- α (alpha)
- Rate of change in demand elasticity: larger values mean demand decays faster as price rises.
- k
- k sets how many log10 units the curve spans, from its value at low prices down to its floor at high prices. It is held fixed at one value across all curves — rather than estimated separately for each — so that differences in the fitted α reflect real differences in demand, not an arbitrary split between the two parameters. The default of 2 is a reasonable starting point for percentage-scale data — demand asymptotes to about 1% of Q0 — and can be changed in the results settings to suit your own data.
Derived indices
- AUC
- A model-free summary of overall demand intensity across the tested price range, adapting the trapezoidal method of Myerson, Green, & Warusawitharana (2001). Unlike the indices below, it needs no successful model fit at all — it is computed directly from the aggregated data. Demand is normalized to its own maximum, as in the original method; price is normalized on a log10 scale instead of linearly, following Borges, Kuang, Milhorn, & Yi (2016), who showed that on pseudoexponentially-scaled data — where intervals between tested points grow larger as they get larger, as is conventional for both delay-discounting and HPT price grids — linear normalization lets the gap between the two highest values dominate the entire area, drowning out behavior at every value actually experienced by most respondents. The area under the resulting curve is found by the trapezoidal rule and is bounded between 0 (demand collapses immediately as price rises off the floor) and 1 (demand stays at its maximum across the whole tested range). Price 0 cannot be log-transformed directly: rather than the fixed offset Borges et al. add before transforming delay (a reasonable choice when the unit is always one day, which does not hold for price in arbitrary currencies or scales), a tested price-0 condition is placed at the same pseudo-position used to plot it on the main chart — one decade below the lowest positive price — so it is included in AUC rather than dropped.
- P50
- The price at which 50% of respondents still purchase (for quantity data, the price at which demand falls to half of fitted Q0), obtained by solving the fitted model for price. It is not reported when the fitted curve never crosses that level, and is flagged as extrapolated when it falls outside the range of prices presented to respondents.
- Pmax
- The price at which demand transitions from inelastic to elastic — below Pmax, total spending rises as price rises; above it, spending falls. It is calculated exactly as the price where the slope of the demand curve equals −1 in log–log terms, using the Lambert W function (Gilroy et al., 2019): Pmax = −W0(−1/(k·ln 10)) / (αQ0). When k is set below ≈ 1.18, demand never reaches unit elasticity and Pmax is not reported.
- Omax
- The value of demand at Pmax (price × predicted demand at that price). For yes/no data this is the expected revenue per person offered the product at Pmax, since demand there is a purchase rate, not a quantity; for quantity data it is the conventional peak spending per person.
For yes/no data, Q is a percentage (0–100), the same scale shown on the main chart's y-axis — so before it can be multiplied by a price it is first converted to a probability by dividing by 100: revenue at price P = P · Q(P)/100. Multiplying by the raw percentage number instead would give a total across however many people that percentage happens to be “out of,” rather than an unambiguous per-person figure — dividing by 100 first is what lets the result scale cleanly to any group size (for example, multiplying by 10,000 to project revenue for a target population of that size).
Pmax and Omax are most useful when price in your study represents an actual payment, fee, or cost-recovery mechanism — for example, setting a sustainable premium or program fee. When price instead stands in for something else, such as the intensity of a preference with no real transaction attached, these two indices don't correspond to a decision anyone would act on, and can be disregarded.
A revenue curve (price × predicted demand) is available directly below the main chart when Pmax is reported. Because the model's demand never falls all the way to zero — it flattens out at a floor near 1% of Q0, controlled by k — plotting revenue across a very wide price range can make it appear to rise again at extreme prices, purely because a small constant floor of demand is being multiplied by an ever-larger price. To avoid showing this artifact as if it were real, the curve stops once predicted demand falls below 3% of Q0, and never extends past the highest price actually tested.
Fit diagnostic
- R²
- How well the fitted curve describes your data — the proportion of the variability in the aggregated demand values that the curve accounts for. It is computed as 1 − RSS/TSS, where RSS (the residual sum of squares) measures how far the data points fall from the fitted curve, and TSS (the total sum of squares) measures how spread out the data points are overall. Values closer to 1 mean the curve fits the data more closely, while values near zero mean it fits poorly; demand studies commonly report values above 0.9 for aggregate data.
Fitting procedure
Curves are fitted by bounded nonlinear least squares on the aggregated
points at positive prices, replicating
nls(..., algorithm = "port") in R with the same
constraints (for percentage data: α ∈ [0, 0.1],
Q0 ∈ [0, 100]). The implementation uses
Levenberg–Marquardt with analytic gradients and multiple starting values,
so it does not depend on a lucky initial guess.
If the survey includes a free (price-0) condition, its aggregated value is always shown in the table and plotted at an arbitrary position on the log-scaled price axis (marked “0”). How it enters the model is a setting: excluded from fitting (the default), included as an ordinary data point, or used to fix Q0 at the observed price-0 demand, in which case only α is estimated.
Individual breakpoints (yes/no data)
For binary purchase data, the analyzer also derives an individual breakpoint for each respondent — the price at which willingness to purchase transitions from “Yes” to “No.”
Because binary responses do not support the full set of nonsystematic-data criteria proposed by Stein et al. (2015), including rules based on bounces and reversals from zero, an adapted reversal-based criterion is used: a response pattern is classified as systematic when it contains no more than two reversals, defined as adjacent transitions from “No” to “Yes” across the ascending price sequence — that is, endorsement of purchase at a higher price after rejection at a lower price. Respondents whose patterns exceed this threshold are excluded from breakpoint analyses.
For eligible respondents, the breakpoint marks the terminal transition to rejection: it is calculated as the geometric mean of the last “Yes” price and the first “No” price that follows it. An isolated earlier “No” — the kind of lapse the reversal criterion tolerates — does not define the breakpoint. Respondents who endorse purchase at every price (including any who return to “Yes” at the highest price), or at none, have no computable breakpoint and are counted separately in the summary table.
Privacy
All parsing, aggregation, and fitting run in your browser. Nothing you upload is transmitted or stored on any server; sessions are saved only to your browser's local storage on your device.
References
Borges, A. M., Kuang, J., Milhorn, H., & Yi, R. (2016). An alternative approach to calculating area-under-the-curve (AUC) in delay discounting research. Journal of the Experimental Analysis of Behavior, 1–11. https://doi.org/10.1002/jeab.219
Gilroy, S. P., Kaplan, B. A., Reed, D. D., Hantula, D. A., & Hursh, S. R. (2019). An exact solution for unit elasticity in the exponential model of operant demand. Experimental and Clinical Psychopharmacology, 27(6), 588–597. https://doi.org/10.1037/pha0000268
Jacobs, E. A., & Bickel, W. K. (1999). Modeling drug consumption in the clinic using simulation procedures: Demand for heroin and cigarettes in opioid-dependent outpatients. Experimental and Clinical Psychopharmacology, 7(4), 412–426. https://doi.org/10.1037/1064-1297.7.4.412
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. https://doi.org/10.1037/pha0000045
Myerson, J., Green, L., & Warusawitharana, M. (2001). Area under the curve as a measure of discounting. Journal of the Experimental Analysis of Behavior, 76(2), 235–243. https://doi.org/10.1901/jeab.2001.76-235
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. https://doi.org/10.1037/pha0000020