Changelog
Source:NEWS.md
emaxnls 0.1.1.9000
Bug fixes
simulate()andconfint(simultaneous = TRUE)/summary(simultaneous = TRUE)now degrade gracefully on platforms where themvtnormshared object is installed but fails to link at runtime (observed on some clang-based Rhub builders). A warning is issued and the computation continues using base-R fallbacks: Cholesky-based multivariate normal sampling forsimulate(), and a Bonferroni-corrected normal quantile for simultaneous confidence intervals. The fallback intervals are conservative but valid (#52).The tibble package is now listed under
Suggestsrather thanImports, making it a genuine optional dependency. All package functionality works with or without tibble installed (#24).
New features
emax_nls(),emax_logistic(),emax_nls_init(), andemax_logistic_init()now havecovariate_model = NULLas a default. Whencovariate_modelis omitted, an intercept-only hyperbolic Emax model is fitted — equivalent to supplyinglist(E0 ~ 1, Emax ~ 1, logEC50 ~ 1)explicitly. Sigmoidal models still require an explicitlogHill ~ 1term in the covariate model. All existing calls that supplycovariate_modelexplicitly continue to work without modification (#69).emax_converged()now returns a named logical scalar. Thenamesattribute holds a short description of the outcome:"converged"on success,"maximum time exceeded"when themax_timelimit was hit,"maximum iterations exceeded"when the optimiser ran out of iterations, or the raw optimiser error message for any other failure. The value itself is stillTRUE/FALSE, so all existing code that checksif (emax_converged(mod))continues to work without modification. The SCM history returned byemax_scm_history()gains a newconvergence_reasoncolumn (character) that records this information for every model tested during the procedure (#62).emax_scm_forward()andemax_scm_backward()now accept acriterionargument ("p-value","aic", or"bic"). Whencriterion = "aic"or"bic", terms are added or removed based on whether they strictly improve the information criterion rather than a p-value threshold, and thethresholdargument is ignored. The default remains"p-value", preserving existing behaviour. The history returned byemax_scm_history()gains acriterioncolumn recording which selection rule was applied in each step (#68).-
Adds an
erplotsmodel interface so thatemaxnlsandemaxlogisticobjects work seamlessly witherplots::er_plot_add_model(),er_plot_add_summary(),er_plot_add_quantiles(), and the VPC pipeline. Three S3 methods are registered lazily at load time (no hard dependency on erplots):-
er_predict()returns point predictions and confidence intervals on a user-supplied exposure grid, with predictions on the probability scale foremaxlogisticmodels. -
er_simulate()returnsnsimmean-curve draws reflecting parameter uncertainty only (no residual noise), suitable for spaghetti/ribbon plots. -
er_summary()returns a coefficient table and a model-level glance row;p_valueis alwaysNULLbecause Emax models have no single privileged parameter.
Covariates present in the model but absent from the exposure grid passed by erplots are filled in automatically with reference values (numeric: column mean; factor/character: first factor level) (#65).
-
Adds a
max_timeargument toemax_nls_options()andemax_logistic_options()that sets a maximum elapsed time (in seconds) for model fitting. If the optimiser has not converged within the limit it is terminated and the model is treated as non-converged, consistent with any other convergence failure. Defaults toInf(no limit). This is particularly useful when running many models in an SCM procedure, where a single pathological fit can otherwise stall the entire covariate search (#16).Adds
emax_logistic()for fitting binary-outcome Emax models using iterative reweighted least squares (IRLS), along withemax_logistic_init()andemax_logistic_options()for initialisation and configuration. All standard S3 methods (coef(),vcov(),confint(),residuals(),fitted(),predict(),anova(),logLik(),AIC(),BIC(),deviance(),simulate()) are supported for the newemaxlogisticclass.-
Redesigns
print()andsummary()methods foremaxnlsandemaxlogisticobjects:print()is now a concise model overview showing structural and covariate formulas, fit statistics (observations, residual df, sigma or deviance, AIC), and a coefficient table with estimates, standard errors, and confidence intervals. Hypothesis tests are not shown byprint(); a footer line directs users tosummary(). Aconf_levelargument controls the interval level (default 0.95).-
summary()gains three new arguments:-
suppress_nonsensical = TRUE: suppresses the test statistic and p-value forlogEC50_Interceptby default. The logEC50 intercept is estimated on the log-concentration scale, so testingH0: logEC50 = 0corresponds to testing EC50 = 1 on the concentration scale — a threshold with no pharmacometric meaning. The confidence interval for logEC50 is always reported. Passsuppress_nonsensical = FALSEto restore the raw test. -
p_adjust = "none": adjusts non-NA p-values viap.adjust()for multiple-comparison correction; suppressed p-values are excluded from the adjustment set. -
simultaneous = FALSE: whenTRUE, computes simultaneous Wald confidence intervals usingmvtnorm::qmvnorm()on the correlation matrix fromvcov(), giving intervals with joint coverage atconf_levelacross all parameters simultaneously.
-
summary(back_transform = TRUE)now also sets the test statistic toNAfor back-transformed parameters, consistent with the standard error already beingNAon the back-transformed scale.
confint()now falls back to Wald intervals with a warning if profile likelihood computation fails (which can occur for sigmoidal models).
Documentation
Switches package language from en-US to en-GB for consistency with the broader er* package family (ertte, erglm, erplots). All documentation, roxygen comments, vignettes, and code comments now use UK English spelling throughout (#61).
Expands the
summary()documentation to explain the relationship between thep_adjustandsimultaneousarguments. The two are independent tools for multiplicity —p_adjustcorrects the hypothesis-test p-values, whilesimultaneouswidens the confidence intervals — and they use different machinery, so their reject/retain decisions need not agree. The new “Multiplicity: p-value adjustment versus simultaneous intervals” section spells out what each argument changes, why the adjusted p-values and the simultaneous intervals may disagree, and which tool to reach for (#47).
Bug fixes
Fixes
AIC()andBIC()when called with multiple model arguments (#37).Fixes
na.actionparameter not being passed through correctly inemax_nls()andemax_logistic()(#38).Fixes
predict()omittingresidual.scalefrom the return value whense.fit = TRUE(#39).Fixes crashes in
emax_logistic_init()and preventsInfparameter bounds arising during initialisation (#40).Hardens
.nls_call()to avoid cryptic errors when optimisation fails, and tightens argument validation inemax_fun()(#41).Adds input validation for the binary response variable in
emax_logistic(), with informative errors for non-binary or out-of-range values (#42).Fixes validator error messages to reference public API parameter names rather than internal names (#43).
Fixes
NaNproduced by.binomial_deviance()when predicted probabilities are exactly 0 or 1 (boundary cases) (#44).confint()now accepts asimultaneousargument, mirroringsummary(). Previouslyconfint(object, simultaneous = TRUE)silently ignored the argument (swallowed by...) and returned pointwise intervals. Settingsimultaneous = TRUEnow returns simultaneous (joint) Wald intervals that match those reported bysummary(object, simultaneous = TRUE)(#46).
emaxnls 0.1.1
CRAN release: 2026-06-30
- Expanded description of package.
- Fixes bug when
emax_nls_init()is called manually. -
anova()now warns rather than errors when fewer than two converged models are supplied. - Additional examples in documentation.
- Improved unit tests.
emaxnls 0.1.0
Initial CRAN submission. The package provides tools for fitting and analysing Emax dose-response models via nonlinear least squares.
Model fitting
emax_nls()fits continuous-response Emax models using NLS, supporting both the hyperbolic (E0 + Emax * x / (EC50 + x)) and sigmoidal (E0 + Emax * x^Hill / (EC50^Hill + x^Hill)) model forms.emax_nls_options()configures the optimisation algorithm and control parameters. Three algorithms are supported via theoptim_methodargument:"gauss"(Gauss-Newton, default),"port"(bounded nl2sol), and"levenberg"(Levenberg-Marquardt viaminpack.lm).emax_nls_init()generates starting values and parameter bounds automatically from the data, including support for categorical covariates. Users can also call it directly to inspect or override the initialisation before fitting.
Covariate modelling
Covariates can be added to any structural parameter (E0, Emax, logEC50, logHill) via a formula interface, e.g.
emax_nls(rsp ~ dose, data = df, E0 = ~ group + age).emax_add_term()andemax_remove_term()update a fitted model by adding or removing a single covariate term without refitting from scratch.
Stepwise covariate modelling (SCM)
emax_scm_forward()performs forward covariate selection, adding one term at a time while the likelihood-ratio test p-value stays below a threshold.emax_scm_backward()performs backward elimination, removing terms while the p-value exceeds a threshold.emax_scm_history()returns the sequence of models tested during an SCM procedure, including AIC, BIC, and convergence status for each candidate.
S3 methods
print()displays a brief model summary.summary()produces a coefficient table with standard errors, confidence intervals, and hypothesis tests. Aback_transform = TRUEargument re-expresses log-scaled parameters (logEC50, logHill) on their natural scales (EC50, Hill) in the output.coef()extracts the parameter vector; supportsback_transform = TRUE.vcov()returns the estimated variance-covariance matrix.confint()computes profile-likelihood confidence intervals.residuals()andfitted()return model residuals and fitted values.predict()generates predictions, optionally with standard errors.anova()compares nested models by likelihood-ratio test.logLik(),AIC(),BIC(),sigma(),nobs(), anddf.residual()return standard model-fit statistics.simulate()draws Monte Carlo replicates by resampling parameters from the asymptotic normal distribution of the estimates (requiresmvtnorm).emax_fun()extracts a standalone prediction function from a fitted model that can be evaluated at arbitrary dose values and parameter vectors.emax_converged()returnsTRUEorFALSEindicating whether the optimiser converged. All S3 methods handle non-convergent models gracefully by returning anemaxnls_nullobject rather than erroring.