Not all rumen gas production experiments are conducted using the ANKOM RF Gas Production System.
rumenGP provides the function as_rumen_gp() for
importing manually collected gas-volume datasets and pressure-based
datasets into the standard rumen_gp format.
Once imported, the data can be analyzed using the same:
available for ANKOM experiments.
The simplest workflow is to import cumulative gas-production measurements directly.
manual_volume <- data.frame(
Bottle = c(
1, 1, 1,
2, 2, 2
),
Treatment = c(
"Control",
"Control",
"Control",
"Corn",
"Corn",
"Corn"
),
Time = c(
0, 4, 8,
0, 4, 8
),
Gas = c(
0, 20, 40,
0, 35, 60
)
)Convert the dataset into a rumen_gp object:
gp <- as_rumen_gp(
data = manual_volume,
head_col = "Bottle",
treatment_col = "Treatment",
time_col = "Time",
gas_col = "Gas"
)Inspect the resulting object:
gp
#> Head Bottle Rep Treatment Time_h Gas_mL
#> 1 1 1 1 Control 0 0
#> 2 1 1 1 Control 4 20
#> 3 1 1 1 Control 8 40
#> 4 2 2 1 Corn 0 0
#> 5 2 2 1 Corn 4 35
#> 6 2 2 1 Corn 8 60Verify the class:
At minimum, gas-volume datasets must contain:
Bottle identifier
Incubation time
Gas production
Column names may vary and are specified through function arguments.
For example:
rumenGP can also import pressure measurements and convert them to gas volume automatically.
manual_pressure <- data.frame(
Bottle = rep(
1,
10
),
Time = c(
0,
2,
4,
6,
8,
12,
16,
24,
36,
48
),
PSI = c(
0,
0.2,
0.5,
0.8,
1.2,
1.8,
2.5,
3.2,
4.0,
4.5
)
)Convert pressure measurements:
gp_pressure <- as_rumen_gp(
data = manual_pressure,
head_col = "Bottle",
time_col = "Time",
pressure_col = "PSI",
pressure_unit = "psi",
headspace_volume = 60
)Inspect the resulting gas volumes:
Currently supported pressure units are:
psi
kPa
Examples:
or
Pressure measurements require information about headspace volume.
Headspace volume represents the gas space inside the bottle and is not necessarily the same as the total bottle volume.
Example:
Bottle volume = 125 mL
Liquid volume = 75 mL
Headspace volume = 50 mL
When pressure data are imported:
should represent the headspace volume and not the total bottle capacity.
Supported headspace units:
mL
L
Examples:
Pressure datasets occasionally contain slightly negative readings caused by sensor noise or instrument variability.
These values can be automatically corrected.
Imported datasets should be validated before model fitting.
validate_ankom(
gp
)
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> Head Bottle Rep Treatment Time_h Gas_mL
#> 1 1 1 1 Control 0 0
#> 2 1 1 1 Control 4 20
#> 3 1 1 1 Control 8 40
#> 4 2 2 1 Corn 0 0
#> 5 2 2 1 Corn 4 35
#> 6 2 2 1 Corn 8 60The validation procedure checks:
Once imported, manually collected datasets can be analyzed exactly like ANKOM datasets.
groot_fit <- fit_groot(gp)
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
mm_fit <- fit_mm(gp)
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
burr_fit <- fit_burr_xii(gp)
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
inverse_paralogistic_fit <-
fit_inverse_paralogistic(gp)
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.Inspect one fitted model:
Model performance can be compared using several goodness-of-fit statistics.
comparison <- compare_models(
Groot = fit_groot(gp),
MichaelisMenten = fit_mm(gp),
BurrXII = fit_burr_xii(gp),
InverseParalogistic =
fit_inverse_paralogistic(gp),
Gompertz = fit_gompertz(gp)
)
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> Warning in nls.lm(par = start, fn = FCT, jac = jac, control = control, lower = lower, : lmdif: info = 0. Improper input parameters.
#> rumenGP data validation passed.
#> Observations: 6
#> Heads: 2
#> Treatments: 2
comparison
#> Model Bottles Successful_Fits Failed_Fits Mean_R2 Mean_RMSE
#> 1 Groot 2 2 0 -0.8504581 15.39026
#> 2 MichaelisMenten 2 0 2 NaN NaN
#> 3 BurrXII 2 2 0 -4.0124301 25.34022
#> 4 InverseParalogistic 2 2 0 -8.6379664 35.14058
#> 5 Gompertz 2 0 2 NaN NaN
#> Mean_RSS Mean_AIC Mean_BIC Lambda_Boundary
#> 1 503.3062 24.48171 19.25430 0
#> 2 NaN NaN NaN 0
#> 3 1352.8435 28.49555 21.96129 0
#> 4 2590.5823 27.81283 22.58542 0
#> 5 NaN NaN NaN 0The comparison table includes:
rank_models(
comparison
)
#> Model Bottles Successful_Fits Failed_Fits Mean_R2 Mean_RMSE
#> 1 Groot 2 2 0 -0.8504581 15.39026
#> 2 MichaelisMenten 2 0 2 NaN NaN
#> 3 BurrXII 2 2 0 -4.0124301 25.34022
#> 4 InverseParalogistic 2 2 0 -8.6379664 35.14058
#> 5 Gompertz 2 0 2 NaN NaN
#> Mean_RSS Mean_AIC Mean_BIC Lambda_Boundary Rank_R2 Rank_RMSE Rank_AIC
#> 1 503.3062 24.48171 19.25430 0 1 1 1
#> 2 NaN NaN NaN 0 4 4 4
#> 3 1352.8435 28.49555 21.96129 0 2 2 3
#> 4 2590.5823 27.81283 22.58542 0 3 3 2
#> 5 NaN NaN NaN 0 5 5 5
#> Rank_BIC
#> 1 1
#> 2 4
#> 3 2
#> 4 3
#> 5 5Current built-in models include:
The Groot and generalized Michaelis-Menten models are mathematically equivalent.
Parameter correspondence:
Both formulations produce identical:
when convergence is achieved.
The Log-logistic formulation:
\[ V(t) = VF \frac{(rt)^a} { 1+(rt)^a } \]
can be rewritten as:
\[ V(t) = VF \frac{t^a} { t^a+(1/r)^a } \]
which is mathematically identical to both the Groot and generalized Michaelis-Menten models.
Parameter correspondence:
| Groot | Generalized Michaelis-Menten | Log-logistic |
|---|---|---|
| VF | A | VF |
| b | K | 1/r |
| k | c | a |
Therefore:
Groot
=
Generalized Michaelis-Menten
=
Log-logistic
These parameterizations describe the same underlying curve.
For this reason, rumenGP does not implement a separate Log-logistic fitting routine because the curve is already represented through the existing Groot and generalized Michaelis-Menten implementations.
A practical workflow is:
1. Import and validate data
2. Fit several biologically plausible models
3. Verify convergence
4. Inspect fitted curves
5. Examine residuals
6. Compare RMSE
7. Compare AIC and BIC
8. Evaluate parameter plausibility
9. Select the most appropriate model
No single model should be considered universally superior.
Model performance depends on:
Produces:
Provide either gas_col or pressure_col.
Produces:
Provide only one of gas_col or pressure_col.
The as_rumen_gp() function allows rumenGP to be used
with:
Once imported, all datasets become standard rumen_gp
objects and can be analyzed using the complete rumenGP workflow,
including:
The same modeling workflow can therefore be applied consistently across ANKOM and non-ANKOM gas-production experiments.