FitCurves() is now superseded by
fit_demand_fixed(). FitCurves() will continue
to work but emits a soft deprecation warning. The new function provides
a modern S3 interface with summary(), tidy(),
glance(), predict(), and plot()
methods. See vignette("migration-guide") for migration
instructions.
FitMeanCurves() is now superseded by
fit_demand_fixed(agg = "Mean") or
fit_demand_fixed(agg = "Pooled").
fit_demand_mixed() now supports the Koffarnus et
al. (2015) exponentiated equation via
equation_form = "koff". This enables fitting demand curves
using the same equation form available in FitCurves()
within the modern hierarchical mixed-effects framework. The
k parameter can be user-specified or auto-calculated from
data range.augment() methods for all model classes provide
fitted values and residuals in a tidy tibble:
augment.beezdemand_fixed(): Returns
.fitted, .residaugment.beezdemand_hurdle(): Returns
.fitted, .fitted_link,
.fitted_prob, .resid,
.resid_responseaugment.beezdemand_nlme(): Returns
.fitted, .resid, .fixedNew compare_models() function for unified model
comparison across all beezdemand model classes. Reports AIC, BIC,
delta_AIC, delta_BIC, and performs likelihood ratio tests when models
are from the same backend and nested.
New anova() S3 methods for comparing nested
models:
anova.beezdemand_hurdle(): LRT for nested hurdle
modelsanova.beezdemand_nlme(): Delegates to
nlme::anova.lme()New check_demand_model() generic with methods for
all model classes. Performs comprehensive diagnostics including
convergence checks, boundary condition detection, random effect variance
assessment, and residual outlier detection. Returns structured
diagnostics object with issues and recommendations. (Named
check_demand_model() to avoid conflict with
performance::check_model().)
New plot_residuals() function creates diagnostic
plots: residuals vs fitted, histogram of residuals, and Q-Q plots. Works
with all model classes via the augment()
infrastructure.
New plot_qq() function creates Q-Q plots for random
effects to assess normality assumptions in hurdle and NLME
models.
alpha_star (normalized
alpha, Strategy B; Rzeszutek et al., 2025), which makes the elasticity
parameter comparable across different values of k.
Available in FitCurves() output (columns
alpha_star and alpha_star_se),
tidy() on beezdemand_fixed objects, and
tidy() on beezdemand_hurdle objects. Standard
errors are obtained via the delta method. See
?param-registry for details.New get_empirical_measures() as a modern replacement
for GetEmpirical(). Returns a
beezdemand_empirical S3 object; access the results via
$measures.
New get_descriptive_summary() as a modern
replacement for GetDescriptives(). Returns a
beezdemand_descriptive S3 object; access the results via
$statistics.
New get_k() as a modern replacement for
GetK(). Returns a single numeric k value with optional
verbose output.
New confint() methods for extracting confidence
intervals from all model classes: beezdemand_fixed,
beezdemand_hurdle, beezdemand_nlme, and
cp_model_nls.
New migration guide vignette
(vignette("migration-guide")) documenting the transition
from FitCurves() to
fit_demand_fixed().
summary() methods for beezdemand_hurdle
and beezdemand_nlme now return structured summary objects
instead of printing directly. Use print(summary(fit)) for
console output. Programmatic access is now possible:
s <- summary(fit); s$coefficients.
fit_demand_hurdle() now fits demand parameters in
natural-log space (log_q0, log_alpha,
log_k) and reports back-transformed values; the
param_space argument has been removed.
fit_cp_nls() now uses log10-parameterized optimizer
coefficients (log10_qalone, I,
log10_beta) across equation forms; the
"exponential" form fits on the log10(y)
response scale and filters y <= 0 with a warning.
predict.cp_model_nls() now always returns
y_pred on the natural y scale; for
"exponential" it additionally returns
y_pred_log10 (and no longer returns
y_pred_natural).
New fit_demand_fixed() function provides a modern
interface for individual demand curve fitting. Returns a structured S3
object with summary(), tidy(), and
glance() methods. This wrapper offers the same
functionality as FitCurves() but with a standardized
API.
New systematicity wrappers with unified output vocabulary:
check_systematic_demand() for purchase task data (wraps
CheckUnsystematic())check_systematic_cp() for cross-price data (wraps
check_unsystematic_cp())Both return beezdemand_systematicity objects with
identical column schemas (differing only in NA values for
domain-specific fields).
First-class tidy() and glance() support
is now guaranteed across all beezdemand model classes. All methods
return tibbles with standardized columns including
model_class and backend.
All summary objects now inherit from
beezdemand_summary base class, enabling shared fallback
behavior and consistent field availability.
This release introduces Stability Contracts for all model classes:
summary() objects now return structured S3
objects with class
c("summary.<class>", "beezdemand_summary"). Required
fields include: call, model_class,
backend, nobs, n_subjects,
converged, logLik, AIC,
BIC, coefficients (tibble),
notes.
tidy() methods return tibbles with columns:
term, estimate, std.error,
statistic, p.value. Multi-part models include
a component column (e.g., “fixed”, “variance”,
“derived”).
glance() methods return 1-row tibbles with
columns: model_class, backend,
nobs, n_subjects, converged,
logLik, AIC, BIC.
fit_cp_nls() and fit_cp_linear() now
accept x_var/y_var to map non-standard column
names to canonical ones ("x", "y").
fit_cp_linear() additionally accepts id_var,
group_var, and target_var. Default behavior is
unchanged when these arguments are omitted.
fit_cp_linear() gains explicit
filter_target and target_level top-level
arguments (previously these were handled implicitly via
validate_cp_data()). Existing calls without these arguments
are unaffected.
fit_cp_nls(start_vals=) is deprecated in favor of
start_values=. The old argument still works but emits a
deprecation warning.
The following deprecations will take effect in version 0.2.0:
beezdemand::pull() is deprecated in favor of
dplyr::pull(). The beezdemand version was a legacy helper
that predates the dplyr function.
The inverse_fun argument in
summary.cp_model_nls(), plot.cp_model_nls(),
and predict.cp_model_nls() is deprecated in favor of
inv_fun for consistency with mixed-effects model
methods.
Standardized argument names across cross-price model methods
(inv_fun instead of inverse_fun)
Cross-price plot methods now have consistent argument ordering
across plot.cp_model_nls(),
plot.cp_model_lm(), and
plot.cp_model_lmer()
Key user-facing functions now return tibbles for better compatibility with
tidyverse workflows: predict.cp_model_nls(),
predict.cp_model_lm(), tidy.cp_model_nls(),
glance.cp_model_nls()
Added standardized error helpers
(validation_error(), fitting_error(),
missing_package_error()) for consistent error
messaging
check_unsystematic_cp() now returns an object of
class cp_unsystematic with proper summary()
method dispatch (no longer overrides
summary.tbl_df())
Added comprehensive hurdle model functionality using TMB (Template Model Builder):
fit_demand_hurdle(): Fit two-part hurdle models with
2 or 3 random effects
Part I models probability of zero consumption (logistic regression with random intercept)
Part II models log-consumption given positive response (nonlinear mixed effects)
S3 methods for beezdemand_hurdle objects:
print(), summary(),
coef(), logLik(), AIC(),
BIC()
predict(): Extract subject parameters or predict
demand/probability
plot(): Visualize demand curves, zero probability,
parameter distributions
Utility functions:
calc_omax_pmax(): Calculate Pmax and Omax from
demand parameters
get_subject_pars(): Extract subject-specific
parameter estimates
compare_hurdle_models(): Likelihood ratio test for
model comparison
get_hurdle_param_summary(): Summary statistics for
individual parameters
Simulation functions:
simulate_hurdle_data(): Generate synthetic hurdle
model data
run_hurdle_monte_carlo(): Monte Carlo simulation
studies
New vignette “Hurdle Demand Models” with comprehensive examples
New dataset apt_full: Full alcohol purchase task
data with 1,100 subjects and demographic covariates
Added comprehensive cross-price demand model functionality:
check_unsystematic_cp(): Check for unsystematic data
in cross-price models
fit_cp_nls(): Nonlinear model fitting for
cross-price demand data
fit_cp_linear(): Linear model fitting for
cross-price demand data with options for fixed effects and mixed-effects
models
New utility functions for cross-price model objects:
summary(), plot(), glance(),
and tidy() methodsextract_coefficients(): Extract model coefficients
in tidy format
cp_posthoc_slopes() and
cp_posthoc_intercepts(): Post-hoc comparisons for model
parameters
validate_cp_data(): Validate and filter cross-price
demand data
Added new vignette “How to Use Cross-Price Demand Model Functions” demonstrating:
Required data structure for cross-price analyses
Checking for unsystematic data
Both two-stage and pooled model fitting approaches
Linear and mixed-effects modeling options
Model visualization and coefficient extraction
Post-hoc comparisons
No longer relies on nlmrt and instead relies on
nlsr
Fixes an issue where CheckUnsystematic may not flag certain cases
when data are passed as tibble
Fixes deprecated arguments in ggplot2
Add ability to specify a start value for alpha in
ExtraF() function
FitCurves(). These
arguments are constrainq0, startq0, and
startalpha. These arguments allow Q0 to be constrained so
alpha is the only fitted parameter and allow for user-specified starting
values.One major change that might affect previous scripts is that in output summary tables, the column formally named ID is now named id (lowercase)
Cleaned up a few things here and there. The package is close for submission to CRAN as it passes R CMD check with no errors, warnings, or notes
GetSharedK() updated to work better and faster at
finding a reasonable value
Internal helper functions added to optimize
GetSharedK()
ExtraF() now compares alpha and Q0
A number of functions now allows you to specify the column names
FitCurves() correctly pulls alpha and q0 standard
errors when k is fitted as a free parameter. Also no longer accepts data
transformations. Must be done prior to fitting using
ChangeData().
FitCurves() now fits mean/pooled data based on
method argument.
GetSharedK() no longer accepts data
transformations.
New ChangeData() will soon serve as the replacement
to ReplaceZeros() and other arguments specified in
FitCurves().
For the time being, FitCurves() will actually output
a list object. This may cause failures with old scripts. Try modifying
scripts to take the first element out of the list. This will soon be
taken care of.
New FitMeanCurves() will fit curve to averaged or
pooled data. Can also make plots.
FitCurves() can now make plots.
GetDescriptives() can make box and whisker
plots.