Flag implausible and outlying body weight records, then decide for each pig whether its weight data are good enough for growth analysis.
clean_weight(visits, qc = qc_config(), verbose = 1, cores = 1)Visit table from prep_visits().
QC settings from qc_config(). Used here: weight_range,
adapt_days, weight_track, track_tol, weight_outlier,
outlier_combine, rlm_cutoff, sd_max, loess_span,
min_records, min_test_days, max_missing_rate, entry_weight_max,
exit_weight_min, track_flag_share, smooth_r2_min.
0 (silent), 1 (summary, default) or 2 (details).
Number of CPU cores for the per-pig computations. Default 1.
An object of class ppt_weight (a list):
per_pig: one row per pig with n_records, n_valid,
n_outliers, first_date, last_date, test_days,
missing_rate, entry_weight, exit_weight (kg, from the LOESS
smooth of the valid weights), r2 (R² of that smooth),
track_removed (share of the records removed by the
tracking, NA when not tracked), longest_gap_days (longest time
without a visit), weight_jump_kg (from prep_visits(), NA
without station transfer), status ("keep",
"low_confidence" or "removed") and reason;
daily: one row per pig and day for pigs not removed: median of the
valid weights (weight, kg), n_records, n_outliers;
records: every weight record with fitted, outlier and
qc_flag (why it was flagged; "track" for records removed by the
tracking);
removed: pigs removed here, plus misreads logged by
prep_visits();
settings: the QC settings used.
Pig checks use the valid (non-outlier) records only:
n_valid < min_records, test_days < min_test_days or
missing_rate > max_missing_rate (share of test days without a valid
weight) remove the pig;
entry_weight > entry_weight_max, exit_weight < exit_weight_min,
a tracking that removes more than track_flag_share of the records,
or r2 < smooth_r2_min mark the pig "low_confidence" but keep it: its
growth can still be estimated by extrapolation in calc_adg(), with a
flag;
so do a test interrupted for more than max_gap_days days (no visit
at all, e.g. isolation for treatment: growth and intake around it are
often not typical of the pig) and a body weight jump above
max_jump_kg at a station transfer.
prep_visits() for the previous step, qc_config() for the
settings.
visits <- prep_visits(nedap, verbose = 0)
w <- clean_weight(visits)
#>
#> ── Cleaning body weight (track + rlm + loess) ──────────────────────────────────
#> Weight records 31,472
#> └ adaptation after entry (not used) 3,404 10.8%
#> └ outliers 5,667 18.0%
#> └ by tracking 1,543 4.9%
#> ! Pigs: 28 kept, 1 low confidence, 1 removed 0.7s
w
#>
#> ── <ppt_weight> ──
#>
#> Pigs: 30 (keep 28, low confidence 1, removed 1)
#> $per_pig: 30 rows x 17 columns
#> $daily: 2789 rows x 7 columns
#> $removed: 1 row x 4 columns
#> $records: 31472 rows x 10 columns
# Why pigs were removed
w$removed
#> responder location step reason
#> <char> <char> <char> <char>
#> 1: 15964 101 clean_weight 0 valid weights < 20
# Records flagged as outliers
head(w$records[outlier == TRUE])
#> responder location date seq_days entry_time weight fitted
#> <char> <char> <Date> <int> <POSc> <num> <num>
#> 1: 13913 101 2024-02-19 1 2024-02-19 22:21:41 23.5 NA
#> 2: 13913 101 2024-02-20 2 2024-02-20 01:00:02 23.5 NA
#> 3: 13913 101 2024-02-20 2 2024-02-20 01:05:04 31.0 NA
#> 4: 13913 101 2024-02-20 2 2024-02-20 02:53:50 23.5 NA
#> 5: 13913 101 2024-02-20 2 2024-02-20 04:27:26 24.0 NA
#> 6: 13913 101 2024-02-20 2 2024-02-20 06:52:21 28.5 NA
#> rlm_w outlier qc_flag
#> <num> <lgcl> <char>
#> 1: NA TRUE adaptation
#> 2: NA TRUE adaptation
#> 3: NA TRUE adaptation
#> 4: NA TRUE adaptation
#> 5: NA TRUE adaptation
#> 6: NA TRUE adaptation
# Other outlier methods
w_sd <- clean_weight(visits, qc = qc_config(weight_outlier = c("rlm", "sd")), verbose = 0)
table(w_sd$per_pig$status)
#>
#> keep low_confidence removed
#> 28 1 1