Title: Lactation Curve Model Fitting for Dairy Animals
Version: 0.1.5
Suggests: knitr, rmarkdown, spelling
VignetteBuilder: knitr
Config/Needs/check: spelling
Description: Fits up to 20 nonlinear lactation curve models to dairy animal milk yield data. Models fitted include exponential, polynomial, mixed logarithmic, inverse polynomial, and sigmoid families published between 1923 and 2000. Supports batch processing of multiple animals from a single CSV file, with flexible selection of animals and models. Produces per-animal parameter tables, goodness-of-fit metrics including R-squared (R2), Root Mean Square Error (RMSE), Akaike Information Criterion (AIC), Bayesian Information Criterion (BIC), and a serial autocorrelation statistic, 15 diagnostic figures, and combined cross-animal comparison outputs. References: <doi:10.1085/jgp.5.4.441>, <doi:10.1038/216164a0>, <doi:10.1016/0301-6226(87)90003-0>, <doi:10.4141/cjas87-067>, <doi:10.3168/jds.S0022-0302(00)75136-8>.
License: GPL-3
Encoding: UTF-8
Language: en-GB
RoxygenNote: 7.3.3
Imports: stats, utils, grDevices, graphics
URL: https://github.com/venkatesanraja/LactCurveModels
BugReports: https://github.com/venkatesanraja/LactCurveModels/issues
NeedsCompilation: no
Packaged: 2026-03-25 03:39:51 UTC; hp
Author: Raja TV [aut, cre], Lalremruati PC [aut], Priyadharshini P [aut], Nidhishree NS [aut], Dheeraj Gurjar [aut], Rani Alex [aut], Vikas Vohra [aut]
Maintainer: Raja TV <venkatesanraja09@gmail.com>
Repository: CRAN
Date/Publication: 2026-03-29 17:00:02 UTC

LactCurveModels: Lactation Curve Model Fitting for Dairy Animals

Description

Fits up to 20 nonlinear lactation curve models to daily milk yield data from one or more dairy animals. For each animal the package produces:

When multiple animals are analysed, three additional combined cross-animal outputs are produced: an R2 comparison figure, an RMSE comparison figure, and a best-model overlay figure, plus combined CSV tables.

Quick start

Note: out_dir must always be supplied — choose any folder on your system where you want results saved.

library(LactCurveModels)

# All animals, all 20 models
results <- run_lactation_analysis(
  input_csv_path = "path/to/mydata.csv",
  out_dir        = "path/to/results"
)

# Selected animals and models
results <- run_lactation_analysis(
  input_csv_path   = "path/to/mydata.csv",
  selected_models  = c("Wood_1967", "Wilmink_k005", "Ali_Schaeffer"),
  selected_animals = c("Animal_A", "Animal_B"),
  out_dir          = "path/to/results"
)

Input CSV format

The CSV file must contain exactly three columns:

animal_id

Character identifier for each animal.

dim

Integer fortnightly time index (1 to 20).

dmy

Numeric daily milk yield (kg/day).

Author(s)

Maintainer: Raja TV venkatesanraja09@gmail.com

Authors:

See Also

Useful links:


Calculate goodness-of-fit metrics for a fitted nls model

Description

Calculate goodness-of-fit metrics for a fitted nls model

Usage

calculate_metrics(model, data)

Arguments

model

A fitted nls object.

data

A data frame with column y (observed values).

Value

A named list: R_squared, adj_R_squared, AIC, BIC, RMSE, Durbin_Watson.


Extract parameter standard errors from a fitted nls model

Description

Tries three approaches in order: summary coefficients table, vcov(), and finally returns NAs if both fail.

Usage

calculate_standard_errors(model)

Arguments

model

A fitted nls object.

Value

A named numeric vector of standard errors.


Build a wide parameter-estimates table

Description

Build a wide parameter-estimates table

Usage

create_parameter_table(model_fits)

Arguments

model_fits

Named list returned by fit_lactation_models().

Value

A data frame with one row per model, columns Model, Param_1 ... Param_n, SE_1 ... SE_n.


Build an actual-vs-predicted table

Description

Build an actual-vs-predicted table

Usage

create_predictions_table(data, model_fits)

Arguments

data

Data frame with columns x and y.

model_fits

Named list returned by fit_lactation_models().

Value

A data frame with columns Days, Actual, and one <Model>_Pred column per fitted model.


Build a residuals table (predicted minus actual)

Description

Build a residuals table (predicted minus actual)

Usage

create_residuals_table(data, model_fits)

Arguments

data

Data frame with columns x and y.

model_fits

Named list returned by fit_lactation_models().

Value

A data frame with column Days and one residual column per model.


Fit lactation curve models to a single animal's data

Description

Attempts to fit up to 20 nonlinear lactation curve models using nls() with the "port" algorithm. Models that fail to converge are silently skipped.

Usage

fit_lactation_models(data, selected_models = "all")

Arguments

data

A data frame with columns x (time index), y (milk yield kg/day), and z (x/365, for Morant-Gnanasakthy). Create it with make_animal_df().

selected_models

Either "all" (default) to fit all 20 models, or a character vector of model names to fit a subset. Valid names: "Brody_1923", "Brody_1924", "Parabolic_Exp_Sikka", "Wood_1967", "Wood_Dhanoa", "Cobby_LeDu", "Quadratic_Dave", "Mixed_Log_GS", "Khandekar", "Wilmink_k005", "Wilmink_k_estimated", "Ali_Schaeffer", "Cappio_Borlino", "Papajcsik_Bodero1", "Papajcsik_Bodero2", "Papajcsik_Bodero3", "Inverse_Poly_Nelder", "Log_Quadratic_Adediran", "Morant_Gnanasakthy", "Pollott_Multiplicative".

Value

A named list. Each element corresponds to one successfully fitted model and contains: model (nls object), metrics (list of fit statistics), predictions (fitted values), std_errors (parameter SEs).

Examples

# Minimal toy example (auto-tested)
toy <- data.frame(
  x = 1:10,
  y = c(8, 11, 13, 12, 11, 10, 9, 8, 7, 6),
  z = (1:10) / 365
)
fits <- fit_lactation_models(toy, selected_models = "Wood_1967")


# Full run with all 20 models (takes longer)
fits_all <- fit_lactation_models(toy)

# Selected models only
fits_sub <- fit_lactation_models(toy,
              selected_models = c("Wood_1967", "Wilmink_k005"))


Build the data frame required by the nls fitting functions

Description

Creates columns x (time index), y (milk yield), and z (x / 365, used by the Morant-Gnanasakthy model).

Usage

make_animal_df(animal)

Arguments

animal

A list with elements x and y.

Value

A data frame with columns x, y, z.


Description

Print all four result tables to the console in formatted form

Usage

print_formatted_tables(
  param_table,
  pred_table,
  resid_table,
  summary_metrics_table
)

Arguments

param_table

Output of create_parameter_table().

pred_table

Output of create_predictions_table().

resid_table

Output of create_residuals_table().

summary_metrics_table

Output of print_results().

Value

Invisibly returns NULL (called for side effects).


Description

Print per-model results to the console and return a summary data frame

Usage

print_results(model_fits)

Arguments

model_fits

Named list returned by fit_lactation_models().

Value

A data frame with one row per model and columns Model, R_squared, Adj_R_squared, AIC, BIC, RMSE, Durbin_Watson.


Run lactation curve analysis for one or more dairy animals

Description

Reads a CSV file containing milk yield records, fits up to 20 nonlinear lactation curve models for each animal (or a selected subset of animals and/or models), saves per-animal diagnostic figures and CSV tables, and produces combined cross-animal summary outputs.

Usage

run_lactation_analysis(
  input_csv_path,
  selected_models = "all",
  selected_animals = "all",
  out_dir
)

Arguments

input_csv_path

Character. Full path to the input CSV file. The file must contain exactly these three columns (any column order):

animal_id

Character or factor identifying each animal.

dim

Integer or numeric time index (days-in-milk fortnightly index, i.e. 1, 2, ..., 20).

dmy

Numeric daily milk yield (kg/day).

selected_models

Either "all" (default) to fit all 20 lactation curve models, or a character vector of model names. Valid names: "Brody_1923", "Brody_1924", "Parabolic_Exp_Sikka", "Wood_1967", "Wood_Dhanoa", "Cobby_LeDu", "Quadratic_Dave", "Mixed_Log_GS", "Khandekar", "Wilmink_k005", "Wilmink_k_estimated", "Ali_Schaeffer", "Cappio_Borlino", "Papajcsik_Bodero1", "Papajcsik_Bodero2", "Papajcsik_Bodero3", "Inverse_Poly_Nelder", "Log_Quadratic_Adediran", "Morant_Gnanasakthy", "Pollott_Multiplicative".

selected_animals

Either "all" (default) to analyse every animal present in the CSV, or a character vector of animal IDs that match entries in the animal_id column exactly.

out_dir

Character. Base output directory. A sub-folder is created for each animal. Must be supplied explicitly — there is no default. The directory is created automatically if it does not already exist. Example: out_dir = "D:/lactation_results".

Value

A named list (one element per animal) each containing:

id

Animal ID string.

model_fits

Named list of fitted model objects and metrics.

param_table

Parameter estimates data frame.

pred_table

Actual vs predicted data frame.

resid_table

Residuals data frame.

metrics_df

Per-model goodness-of-fit metrics, sorted by R2.

summary_metrics

Wide summary metrics data frame.

Returned invisibly so large objects are not auto-printed.

Examples


# Build a small example CSV in a temporary directory
tmp_csv <- file.path(tempdir(), "example_animals.csv")
example_data <- data.frame(
  animal_id = rep(c("Animal_A", "Animal_B"), each = 20),
  dim       = rep(1:20, times = 2),
  dmy       = c(
    8.1, 11.2, 13.0, 12.5, 11.8, 11.0, 10.4, 9.8, 9.3, 8.8,
    8.3, 7.9, 7.5, 7.1, 6.8, 6.5, 6.2, 5.9, 5.7, 5.4,
    7.5, 10.1, 11.8, 11.3, 10.7, 10.0, 9.4, 8.9, 8.4, 7.9,
    7.5, 7.1, 6.8, 6.4, 6.1, 5.8, 5.6, 5.3, 5.1, 4.9
  )
)
write.csv(example_data, tmp_csv, row.names = FALSE)

# Analyse all animals with two selected models
results <- run_lactation_analysis(
  input_csv_path  = tmp_csv,
  selected_models = c("Wood_1967", "Wilmink_k005"),
  out_dir         = tempdir()
)

# Analyse one animal only
results2 <- run_lactation_analysis(
  input_csv_path   = tmp_csv,
  selected_models  = c("Wood_1967", "Ali_Schaeffer"),
  selected_animals = "Animal_A",
  out_dir          = tempdir()
)


Safely store a model result in the results list

Description

If fit is a try-error or metrics cannot be computed the function returns results unchanged.

Usage

store_result(results, name, fit, data)

Arguments

results

Named list of already-stored model results.

name

Character. Name to store the result under.

fit

Output of try(nls(...)).

data

Data frame used for fitting (needed for metrics).

Value

Updated results list.


Write the four result tables to CSV files

Description

Write the four result tables to CSV files

Usage

write_tables_to_csv(
  param_table,
  pred_table,
  resid_table,
  summary_metrics_table,
  prefix
)

Arguments

param_table

Output of create_parameter_table().

pred_table

Output of create_predictions_table().

resid_table

Output of create_residuals_table().

summary_metrics_table

Output of print_results().

prefix

Character string prepended to every file name (include trailing path separator + animal ID, e.g. file.path(tempdir(), "Animal_A", "Animal_A_")). Must be supplied explicitly; there is no default to avoid writing to the user's working directory.

Value

Invisibly returns a character vector of the four file paths written.