inferMM provides variance-aware Michaelis-Menten estimation and inference for
enzyme-kinetic data with concentration-dependent heteroscedasticity. The
package supports single-curve analyses, grouped workflows, and clustered
repeated-measurement settings through Michaelis-Menten-specific score-based
estimating routines and companion S3 summaries, plotting, and reporting tools.
The package is designed around a compact workflow:
fit_mm()
fit_mm_moments()
screen_mm()
group_mm()
cluster_mm()
report_mm()
install.packages("inferMM")
The package ships with two demo datasets.
sdl_demo: self-driving laboratory Michaelis-Menten panelalves_demo: filtered soil exoenzyme kinetics panel from Alves et al. (2021)library(inferMM)
data(sdl_demo)
data(alves_demo)
library(inferMM)
one_curve <- subset(sdl_demo, enzyme == "1111")
fit <- fit_mm(
x = one_curve$s_uM,
y = one_curve$v_uM_per_min,
variance = "sqrt"
)
summary(fit)
confint(fit)
Single-curve fits verify standardized mean-score residuals, positive interior parameters, residual variance, and the condition of the scaled information matrix before returning estimates and intervals. The profile search compares all detected acceptable roots by weighted residual sum of squares rather than selecting the first bracket. Score minimization supplies candidates only; it is not automatically treated as convergence. Single-curve Wald covariance uses an unregularized scaled information inverse, not a silent ridge correction. No numerical search guarantees detection of every root or a global minimum.
Diagnostics are stored in fit$convergence. Errors carry class
inferMM_profile_error (also inferMM_convergence_error), with stage, reason,
search bounds, standardized score norm, tolerance and candidate count; a
failed fit returns no estimates or confidence intervals. Check km_bounds,
substrate coverage, outliers, the variance shape and identifiability.
Screening/grouping records failed curves without fabricating results.
Automatic variance selection retains failed candidates with success = 0
and their error messages in variance_candidate_table, selecting only
successful candidates and stopping if all fail. The higher-moment profile
pilot uses the same root checks; the clustered solver retains its own rules.
screen <- screen_mm(
x = one_curve$s_uM,
y = one_curve$v_uM_per_min,
quiet = TRUE
)
screen$table[, c("model", "selected_model", "quasi_aic", "quasi_bic", "rmse")]
Pass a vectorized positive function directly as variance. A descriptive label
is optional and can be attached with variance_function():
h <- variance_function(
function(S) 1 + S / 20,
label = "Var = gamma (1 + S/20)"
)
custom_fit <- fit_mm(one_curve$s_uM, one_curve$v_uM_per_min, variance = h)
summary(custom_fit)
confint(custom_fit)
predict(custom_fit, newdata = c(0, 10, 40), interval = "prediction")
custom_shapes <- list(
linear_floor = function(S) 1 + S / 20,
saturation = function(S) 1 + 9 * S / (20 + S)
)
custom_screen <- screen_mm(
one_curve$s_uM, one_curve$v_uM_per_min,
variance_models = c("constant", "sqrt"),
variance_functions = custom_shapes, quiet = TRUE
)
custom_screen$table[, c("model", "quasi_aic", "quasi_bic", "success")]
Use variance_models = character(0) to compare custom functions only. The same
variance_functions = custom_shapes argument works in group_mm(). Candidate
names identify fits and ranking rows; invalid functions are recorded as failed
candidates instead of preventing the other candidates from being fitted.
The function represents variance shape, not standard deviation or weights. It must be deterministic and pointwise, returning a numeric vector of the same length as its input, with finite strictly positive values at every fitting and prediction concentration. Invalid custom values are rejected, not clipped. Functions must also work on new grids and bootstrap samples; do not return a cached vector or use the input's mean, range, or ordering to define the shape. Use a local closure to capture fixed external constants if necessary.
For each fixed shape, the existing scalar Km profile-score fit and closed-form Vmax and scale updates are retained. Custom functions are preserved for prediction, plotting, and bootstrap refits. Internal normalization does not change the supplied variance model; the reported scale refers to the original shape. Numerical difficulties can still arise for ill-scaled shapes or weakly identified curves.
This interface does not estimate extra shape parameters. Standard errors,
intervals, and the three-parameter working information criteria condition on the
supplied shape and omit external shape-estimation or selection uncertainty.
Prediction bands retain the working-normal approximation. This feature does not
estimate higher conditional moments, prove efficiency gains over same-weight
WNLS, or extend cluster_mm() to user-defined functions. The separate
fit_mm_moments() estimator below adds a higher-moment route.
User-defined variance functions require inferMM 0.1.0 or later. Check the
installed version with packageVersion("inferMM").
fit_mm_moments() uses conditional third and fourth moments to weight joint
mean/variance estimating equations, following Kim and Ma (2012), Section 3,
https://doi.org/10.1007/s10463-011-0332-y. It is an opt-in estimator, not a
replacement for fit_mm() and not a gamma or Student-t likelihood fit.
set.seed(19)
dat <- simulate_mm_data(n = 200, error = "skewed", skew_shape = 4)
h <- function(S) 1 + 9 * S / (20 + S)
# Estimate constant standardized skewness/kurtosis from pilot residuals.
fit_hm <- fit_mm_moments(dat$x, dat$y, variance = h)
summary(fit_hm)
confint(fit_hm, level = 0.95)
fit_hm$vcov_joint # Vmax, Km, and the nuisance variance scale together
# Alternatively, supply fixed working moments of centered gamma errors.
fit_gamma <- fit_mm_moments(dat$x, dat$y, variance = h,
moments = "gamma", shape = 4)
predict(fit_gamma, c(10, 20, 80), interval = "confidence")
# Concentration-dependent standardized moments are also possible.
fit_custom_moments <- fit_mm_moments(
dat$x, dat$y, variance = h, moments = "custom",
skewness = function(S) 0.8 + 0.2 * S / (20 + S),
kurtosis = function(S) 3 + 1.5 * (0.8 + 0.2 * S / (20 + S))^2
)
set.seed(20)
confint(fit_hm, method = "bootstrap", B = 99) # pairs; re-estimates moments
The default covariance = "model" uses joint inverse working information
and needs correct higher moments for its interpretation. Optional
covariance = "sandwich" differentiates the full three-parameter
estimating equations. The
leading mean-parameter block is extracted after accounting for the nuisance
variance scale. moments = "student_t", df = 10 supplies symmetric heavy-tail
moments; simulate_mm_data(error = "student_t", df = 10) generates matching
standardized errors. Normal or constant symmetric working moments yield the
same mean point estimates as the profile equations, not an efficiency gain.
The new estimator uses a joint numerical solve with continuation from the
profile pilot; it does not retain the scalar/closed-form updates of the
default estimator. It reports a score norm and errors on failed/boundary roots
or singular covariance. It does not silently return an old fit as a new one.
Convergence errors identify the fitting stage and reason, total iterations,
scaled score norm, tolerance, and completed continuation fraction where relevant.
They suggest checks for the data, variance shape, and working moments, or a
larger iteration limit when appropriate. They can be handled with
tryCatch(..., inferMM_convergence_error = function(e) ...); the condition
also carries stage, reason, moments, iterations, score_norm,
tolerance, and progress fields. Failed fits return no estimates or intervals.
Failures during non-Gaussian higher-moment continuation also suggest manually
retrying with moments = "normal" while keeping the same variance function.
This changes the working moments; it guarantees neither convergence nor
efficiency under the original non-Gaussian moments. There is no automatic fallback.
Only pointwise mean-confidence bands are available: four moments alone do not
specify predictive quantiles. Working-Gaussian AIC/BIC are not reported for
these non-likelihood roots. screen_mm(), group_mm(), and cluster_mm()
continue to use their original estimators, not this new route.
Efficiency in the conditional mean/variance model requires suitable moment
estimation and regularity. The default estimates constant standardized
moments, not arbitrary conditional moment functions. Correct mean/variance
remain important: a sandwich is not a remedy for bias caused by an incorrect
variance shape in these squared-residual equations. Small-sample performance,
especially high-moment estimation, must be checked; no universal efficiency
or 95% coverage guarantee is made. See ?fit_mm_moments for the equations,
solver, assumptions, and covariance details.
grouped <- group_mm(
data = sdl_demo,
s = "s_uM",
v = "v_uM_per_min",
groups = "enzyme",
variance_models = c("constant", "log", "sqrt", "cuberoot"),
quiet = TRUE
)
grouped$comparison$best_by_group[
, c("group_label", "model", "selected_model", "quasi_aic", "quasi_bic", "rmse")
]
cluster_fit <- cluster_mm(
data = subset(alves_demo, enzyme == "BG"),
s = "substrate_conc",
v = "activity",
cluster = "core",
variance = "sqrt"
)
summary(cluster_fit)
confint(cluster_fit)
Both clustered estimators remove rows with a missing value in any clustering column and issue a warning with the number removed. Cluster counts, cluster sizes, fitted values and residuals then describe only the retained data. Unused factor levels do not create extra clusters. The default profile method supports singleton clusters alongside repeated-measurement clusters; the projected method continues to require at least two readings per cluster.
For sparse clustered fits, default interval reporting is intentionally cautious: printed summaries may suppress intervals, and bootstrap intervals should be read as sensitivity analyses rather than routine default inference.
The opt-in method = "projected" adds an MM-specific adaptation of the
conditional-centering construction of Ma and Genton (2010), Section 3.2,
https://doi.org/10.1111/j.1467-9868.2010.00741.x. It leaves the distribution
of the cluster random effect unspecified while retaining conditionally
independent Gaussian residuals with the chosen fixed variance shape. This is
different from the non-Gaussian residual analysis in fit_mm_moments().
set.seed(351)
substrate <- c(2, 5, 10, 20, 50, 100, 200)
n_clusters <- 60L
b <- 12 * (rgamma(n_clusters, shape = 2) - 2) / sqrt(2)
dat <- data.frame(
cluster = rep(seq_len(n_clusters), each = length(substrate)),
S = rep(substrate, n_clusters)
)
dat$Y <- (100 + b[dat$cluster]) * dat$S / (20 + dat$S) +
rnorm(nrow(dat), sd = sqrt(2 * sqrt(dat$S)))
fit_projected <- cluster_mm(
dat, s = "S", v = "Y", cluster = "cluster",
variance = "sqrt", method = "projected"
)
summary(fit_projected)
confint(fit_projected)
predict(fit_projected, c(10, 20, 80), interval = "confidence")
For each candidate Km, the new path projects observations onto the cluster's MM loading, leaving a residual orthogonal to that loading. A scalar score with the identity instrument estimates Km; Vmax, the residual scale and the random-effect variance moment then have explicit updates. The identity instrument belongs to a consistent estimating-equation class under the stated model and identification conditions, but is not generally the efficient instrument. This implementation does not claim universal efficiency or better finite-sample performance than the legacy estimator.
The new path uses the stacked independent-cluster sandwich, including
mean and variance-moment equations, for standard errors and 95% Wald intervals.
It does not reuse the legacy mean-information covariance. At least five
independent clusters and two readings per cluster are required; larger cluster
counts are important for asymptotic inference. The variance shape must be
correct, and finite fourth random-effect moments are assumed for the joint
covariance. Intervals condition on the supplied or selected variance shape.
Quasi-AIC/BIC remain working-normal marginal screening scores, not likelihood
information criteria for the unspecified random-effect density.
Invalid roots, boundary roots, degenerate variance and singular derivatives
stop with inferMM_cluster_projected_error; no fallback or ridge is applied.
km_bounds can adjust the positive Km search interval for this path.
Failure conditions include stage, reason, and diagnostics, accessible
with tryCatch(..., inferMM_cluster_projected_error = function(e) e).
Root failures report finite grid counts, candidate/accepted-root counts,
the smallest grid score residual and the associated Km; covariance failures
report available conditioning diagnostics. No fitted object or interval is
returned on failure, and no automatic switch to method = "profile" occurs.
A non-finite tail point does not by itself invalidate a verified interior
root. An incomplete search produces inferMM_cluster_projected_warning
with reason "incomplete_search", stored in fit$convergence$search_warning.
The same warning class with reason "variance_component_boundary" reports
a truncated non-positive variance moment; it is not mean-score failure.
Inspect fit$convergence$joint_score_norm, $search, and $bread_rcond.
Passing these checks is not a guarantee of global optimality or adequate
information from a narrow concentration range.
Only pointwise mean-confidence bands are provided, not prediction bands:
the random-effect density has not been specified. A negative random-effect
variance moment is reported as zero with a warning; that truncation affects
marginal variance reporting, not mean estimation or its covariance. Bootstrap
refits preserve the projected method. Existing calls without method retain
the legacy profile/moment algorithm and its covariance.
report_mm(fit, interval_type = "confidence")
plot(grouped, interval_type = "confidence")
predict(fit, newdata = seq(0, 80, length.out = 6), interval = "prediction")
R/: package source codeman/: function documentationdata/: bundled .rda demo datainst/extdata/: raw CSV mirrors of the demo datavignettes/: end-to-end workflow vignettetests/: unit testsThis package source is focused on the reusable software interface, bundled example data, documentation, and tests. Manuscript-specific reproducibility materials can be distributed separately from the package source when needed.