| fit_cp_nls | R Documentation |
Fits a cross-price demand curve using log10-parameterization for numerical stability. The optimizer estimates parameters on the log10 scale where applicable, ensuring positive constraints are naturally satisfied.
Equation forms:
Exponentiated (default):
y = Q_{alone} \cdot 10^{I \cdot \exp(-\beta \cdot x)}
Exponential (fits on log10 response scale):
\log_{10}(y) = \log_{10}(Q_{alone}) + I \cdot \exp(-\beta \cdot x)
Additive (level on y):
y = Q_{alone} + I \cdot \exp(-\beta \cdot x)
where x is the alternative product price (or "cross" price) and y
is consumption of the target good.
Optimizer parameters (log10 parameterization):
log10_qalone: \log_{10}(Q_{alone}) - baseline consumption
when the alternative is effectively absent.
I: cross-price interaction intensity; sign and magnitude reflect
substitution/complementarity. Unconstrained (can be negative for substitutes).
log10_beta: \log_{10}(\beta) - rate at which cross-price
influence decays as x increases.
Natural-scale values are recovered as Q_{alone} = 10^{log10\_qalone} and
\beta = 10^{log10\_beta}.
The function first attempts a multi-start nonlinear least squares fit
(nls.multstart). If that fails—or if explicit start_values are provided—it
falls back to minpack.lm::nlsLM. Optionally, it will make a final attempt
with nlsr::wrapnlsr. Returns either the fitted model or a structured object
with metadata for downstream methods.
fit_cp_nls(
data,
equation = c("exponentiated", "exponential", "additive"),
x_var = "x",
y_var = "y",
start_values = NULL,
start_vals = lifecycle::deprecated(),
iter = 100,
bounds = NULL,
fallback_to_nlsr = TRUE,
return_all = TRUE
)
data |
A data frame with columns for price and consumption. Additional columns are ignored. Input is validated internally. |
equation |
Character string; model family, one of
|
x_var |
Character string; name of the price column in |
y_var |
Character string; name of the consumption column in |
start_values |
Optional named list of initial values for parameters
|
start_vals |
|
iter |
Integer; number of random starts for |
bounds |
Deprecated. Log10-parameterized parameters are naturally unbounded. This argument is ignored but retained for backwards compatibility. |
fallback_to_nlsr |
Logical; if |
return_all |
Logical; if |
Start values. When start_values is missing, the function:
(1) estimates a reasonable range for log10_qalone from the observed y,
(2) estimates log10_beta from the price range, and (3) launches a multi-start
grid in nls.multstart.
Zero handling for exponential equation. Since the exponential equation fits
on the \log_{10}(y) scale, observations with y \le 0 are automatically
removed with a warning. Use the exponentiated or additive forms if you need to
retain zero consumption values.
Fitting pipeline (short-circuiting):
nls.multstart::nls_multstart() with random starts.
If that fails (or if start_values provided): minpack.lm::nlsLM() using
start_values (user or internally estimated).
If that fails and fallback_to_nlsr = TRUE: nlsr::wrapnlsr().
The returned object has class "cp_model_nls" (when return_all = TRUE) with
components: model, method (the algorithm used), equation, start_vals,
nlsLM_fit, nlsr_fit, and the data used. This is convenient for custom
print/summary/plot methods.
If return_all = TRUE (default): a list of class "cp_model_nls":
model: the fitted object from the successful backend.
method: one of "nls_multstart", "nlsLM", or "wrapnlsr".
equation: the model family used.
start_vals: named list of starting values (final used; kept for backward compatibility).
nlsLM_fit, nlsr_fit: fits from later stages (if attempted).
data: the 2-column data frame actually fit.
If return_all = FALSE: the fitted model object from the successful backend.
Check convergence codes and residual diagnostics from the underlying fit.
Poor scaling or extreme y dispersion can make parameters weakly identified.
For "exponential", the model fits on the \log_{10}(y) scale internally.
check_unsystematic_cp for pre-fit data screening,
validate_cp_data for input validation.
## --- Example: Real data (E-Cigarettes, id = 1) ---
dat <- structure(list(
id = c(1, 1, 1, 1, 1, 1),
x = c(2, 4, 8, 16, 32, 64),
y = c(3, 5, 5, 16, 17, 13),
target = c("alt", "alt", "alt", "alt", "alt", "alt"),
group = c("E-Cigarettes", "E-Cigarettes", "E-Cigarettes",
"E-Cigarettes", "E-Cigarettes", "E-Cigarettes")
), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))
## Fit the default (exponentiated) cross-price form
fit_ecig <- fit_cp_nls(dat, equation = "exponentiated", return_all = TRUE)
summary(fit_ecig) # model summary
fit_ecig$method # backend actually used (e.g., "nls_multstart")
coef(fit_ecig$model) # parameter estimates: log10_qalone, I, log10_beta
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.