The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Importing Non-ANKOM Data

Introduction

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.

library(rumenGP)

Importing Gas-Volume Data

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     60

Verify the class:

class(gp)
#> [1] "rumen_gp"   "data.frame"

Required Columns

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:

head_col = "Bottle"
time_col = "Time"
gas_col = "Gas"

Importing Pressure Data

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:

head(gp_pressure)
#>   Head Bottle Rep Treatment Time_h    Gas_mL
#> 1    1      1   1   Unknown      0 0.0000000
#> 2    1      1   1   Unknown      2 0.7140855
#> 3    1      1   1   Unknown      4 1.7852138
#> 4    1      1   1   Unknown      6 2.8563421
#> 5    1      1   1   Unknown      8 4.2845132
#> 6    1      1   1   Unknown     12 6.4267698

Pressure Units

Currently supported pressure units are:

psi
kPa

Examples:

pressure_unit = "psi"

or

pressure_unit = "kPa"

Headspace Volume

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:

headspace_volume = 50

should represent the headspace volume and not the total bottle capacity.

Headspace Units

Supported headspace units:

mL
L

Examples:

headspace_unit = "mL"
headspace_unit = "L"

Negative Pressure Values

Pressure datasets occasionally contain slightly negative readings caused by sensor noise or instrument variability.

These values can be automatically corrected.

negative_pressure <- data.frame(

  Bottle = c(
    1, 1, 1
  ),

  Time = c(
    0, 4, 8
  ),

  PSI = c(
    -0.5,
    0.2,
    1.0
  )

)
gp_negative <- as_rumen_gp(

  data = negative_pressure,

  head_col = "Bottle",

  time_col = "Time",

  pressure_col = "PSI",

  pressure_unit = "psi",

  headspace_volume = 60,

  zero_negative_pressure = TRUE

)

Validation

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     60

The validation procedure checks:

Fitting Models

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:

summary(groot_fit)
#> 
#> Groot model summary
#> -------------------
#> Total bottles: 2
#> Successful fits: 2
#> Failed fits: 0
#> Low R-squared (< 0.90): 2

Comparing Models

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               0

The comparison table includes:

Model Ranking

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        5

Available Models

Current built-in models include:

Model Equivalence

Groot and Generalized Michaelis-Menten

The Groot and generalized Michaelis-Menten models are mathematically equivalent.

Parameter correspondence:

Both formulations produce identical:

when convergence is achieved.

Groot, Generalized Michaelis-Menten, and Log-logistic

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.

Common Errors

No Gas or Pressure Supplied

as_rumen_gp(
  data = my_data,
  head_col = "Bottle",
  time_col = "Time"
)

Produces:

Provide either gas_col or pressure_col.

Both Gas and Pressure Supplied

as_rumen_gp(
  data = my_data,
  gas_col = "Gas",
  pressure_col = "PSI"
)

Produces:

Provide only one of gas_col or pressure_col.

Missing Headspace Volume

as_rumen_gp(
  pressure_col = "PSI"
)

Produces:

headspace_volume must be supplied when pressure_col is used.

Summary

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.

Next Steps

Additional capabilities include custom model development.

See:

?fit_custom

for information about fitting user-defined kinetic models.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.