tidypptsda cheatsheet

Pig performance-testing station data (NEDAP / FIRE): body weight cleaning → ADG → ADFI → FCR

read_station()read export files
→
prep_visits()standard visit table
→
clean_weight()weight QC
→
calc_adg()fill weights + ADG
→
calc_adfi()correct, fill feed
→
calc_fcr()FCR + confidence
→
plot_* / write_results() / write_report()plots, export, HTML report
All in one: run_pipeline(); all thresholds: qc_config()

Install and run everything

# install.packages("pak")
pak::pak("tony2015116/tidypptsda")
library(tidypptsda)

raw <- read_station("export/", station = "nedap")
res <- run_pipeline(raw)            # or run_pipeline(nedap)
res$fcr$per_pig                     # final results
res$removed                         # removed pigs, with reasons
write_results(res, dir = "results", farm = "A01")
write_report(res, "results/report")  # HTML: a page per station, arrow keys

Example data: nedap, fire (raw station exports).

Read data read_station() / station_format()

# a whole folder; without station the type is detected
read_station("export/", station = "nedap")
read_station(c("101.xlsx", "102.xlsx"), station = "fire")
# other column names: write a template, edit column
station_format("fire", file = "fire_format.txt")
read_station("export/", station = "fire",
             format = "fire_format.txt")
TypeRequired fields
NEDAPresponder, location, entry_time, feed_intake, weight
FIREsame + exit_time, trough_in, trough_out

Visits and breed prep_visits() / add_breed()

visits <- prep_visits(raw)
visits <- add_breed(visits, read.csv("breeds.csv"),
                    id = "tag", breed = "breed")

QC settings qc_config()

qc <- qc_config(stage_range = c(60, 120),
                curve_model = "poly1")
qc                          # all 43 parameters, by group
run_pipeline(raw, qc = qc)
ParameterDefaultMeaning
stage_range30–120weight stage of ADG / ADFI / FCR
weight_range15–150valid single weight
adapt_days7adaptation after entry, weights unused
weight_outlierrlm, loessoutlier methods after tracking
min_test_days35shortest test (removes)
curve_modelpoly2curve that fills the stage ends
impute_methodloess_popfeed filling: population curve × pig level; or loess_lm, linear
curve_extrapstartbeyond the records: tangent at the start, curve at the end; or curve, tangent
max_edge_extrap_days15more filling at the ends: low confidence
duration_max3600longest visit (s)

Misspelt names get a suggestion; $settings of every result keeps the settings used.

Weight cleaning clean_weight()

In order: weight range → adaptation → tracking back from the end of the test (keep readings that connect) → quadratic robust regression rlm (weight < 0.5) + LOESS (> 3 MAD off).

qc_flagMeaning
""valid
weight_rangeoutside 15–150 kg
adaptationfirst 7 days after entry
trackdoes not connect (mostly small pigs on the scale together)
rlm / loessflagged by that method
statusWhen
removed< 20 valid weights, test < 35 d, > 30% days missing
low_confidenceentry > 65 kg, exit < 85 kg, tracking removed > 40%, LOESS R² < 0.99
keeppassed

Results: w$per_pig (per pig), w$records (per record).

Daily gain calc_adg()

  1. The growth curve sets the stage: end = first time at the upper limit, start = last rise through the lower limit before it.
  2. Every stage day gets a weight, weight_filled:
sourceFrom
observedmedian of the day's valid weights
interpolatedbetween recorded days: linear interpolation
curvebefore the first record: tangent; after the last: growth curve (curve_extrap)

3. ADG = slope of the daily weights on the day over the stage (g/d), with r_squared.

adg_typeMeaning
observedboth stage limits inside the test
extrapolatedextrapolated, at most 30 days
partiala limit is never reached: covered part only
noneless than 7 days covered, no ADG

Feed intake flag_feed_errors() / calc_adfi()

stateThe day's intake is
orgrecorded, no error visit that day
corrcorrected by the model
iiigap between records: ≤ 3 d LOESS, > 3 d population curve × pig level
elrpstage start: population curve × pig level; stage end: the pig's own regression
missingcannot be estimated

ADFI = mean daily intake over the stage; coverage = share of days recorded (incl. corrected).

Feed conversion calc_fcr()

FCR = ADFI ÷ ADG, gf = ADG ÷ ADFI. fcr_flag is ok or low_confidence; why is in fcr_note:

Per class: fcr$by_bin; summary: fcr$summary (all / ok / per breed). For breeding values prefer pigs with fcr_flag == "ok".

Growth plot plot_adg(adg, weight = w)

light grey dotsvalid raw weight records
×dark grey crossesremoved records (see qc_flag)
blueobserved daily weight
orangeinterpolated daily weight
reddish purpledaily weight from the growth curve
green line + bandgrowth curve, about 95% range
black long dashesADG regression line (slope = ADG)
grey horizontal dashesstage limits

Feed intake plot plot_adfi(adfi)

light greyrecorded daily intake (uncorrected)
blueerror-free, used as recorded (org)
orangecorrected (corr)
greenfilled between records (iii)
reddish purplefilled at the stage ends (elrp)
grey horizontal dashesthe pig's ADFI
g <- plot_adg(res$adg, weight = res$weight,
              locations = "101")
g$plot[[1]]                     # first station
h <- plot_adfi(res$adfi)
save_plots(g, "plots", suffix = "growth")

Export write_results()

Files are farm_table_date.csv, UTF-8 with BOM (opens in Excel without garbled Chinese).

FileContent
fcrADG, ADFI, FCR and flags per pig
by_binfeed, gain, FCR per weight class
daily_weightdaily weights (observed, filled, curve)
daily_feeddaily intake (recorded, corrected, filled)
weight_pigsweight QC per pig
feed_model / summarycorrection model / trait summary
removed / settingsremoved pigs and reasons / settings used

Validation test the methods on your data

FunctionTests
validate_outliers()artificial errors: detection, false removals and ADG error of outlier methods; clean records by consensus
validate_adg()growth curves: blocked cross-validation (block_days) and truncation (late entry, early exit); extrap compares curve and tangent
validate_weight_fill()hide daily weights: linear interpolation vs each curve
validate_adfi()hide daily intake: loess_pop vs loess_lm vs linear; with weight the body weight is computed again
validate_truncation()whole pipeline: drop all visits of some pigs, rerun, compare ADG / ADFI / FCR of several settings (no leakage)
vw <- validate_weight_fill(w, max_pigs = 300, cores = 4)
vw$summary
# scenarios: random30 / blocks3 / late20 / early15
# hidden days are removed before cleaning (no leakage, 1.5.0)
vf <- validate_adfi(f, weight = w)

Common settings

# late entry (45-60 kg)
qc_config(stage_range = c(60, 120), curve_model = "poly1")
# slaughter at about 115 kg
qc_config(stage_range = c(30, 110))
# planned test of 50 days
qc_config(min_test_days = 30)
# FIV limit by body weight + class FCR check
qc_config(fiv_max_by_weight = fiv_max_example(),
          bin_fcr_limits = bin_fcr_example())
# thousands of pigs: parallel
run_pipeline(raw, cores = 4)
# one station, a few pigs
plot_adg(res$adg, locations = "101", responders = c("13913"))