Skip to content

Commit 7e4e3c7

Browse files
JamesHWadeclaude
andcommitted
fix: correct LOD/LOQ k-parameter passthrough and drift correction float comparisons
- LOD/LOQ calibration method now uses user-provided k parameter instead of hardcoded 3.3/10 values (lod-loq.R) - Replace exact `predicted == 0` checks with epsilon-based near-zero tolerance across all 4 drift correction functions to prevent extreme correction factors from near-zero denominators (drift-correction.R) - Fix pkgdown article reference paths missing articles/ prefix (_pkgdown.yml) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b3becbe commit 7e4e3c7

File tree

3 files changed

+27
-24
lines changed

3 files changed

+27
-24
lines changed

R/drift-correction.R

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -289,18 +289,19 @@ bake.step_measure_drift_qc_loess <- function(object, new_data, ...) {
289289
# Predict QC response at each run order
290290
predicted <- stats::predict(loess_fit, newdata = run_order)
291291

292-
# Calculate correction factors (guard against zero predicted values)
292+
# Calculate correction factors (guard against near-zero predicted values)
293+
near_zero <- abs(predicted) < sqrt(.Machine$double.eps)
293294
correction_factors <- ifelse(
294-
predicted == 0 | is.na(predicted),
295-
1, # No correction if predicted is zero or NA
295+
near_zero | is.na(predicted),
296+
1, # No correction if predicted is near-zero or NA
296297
qc_median / predicted
297298
)
298299

299-
# Warn if any zero predictions occurred
300-
n_zero <- sum(predicted == 0, na.rm = TRUE)
300+
# Warn if any near-zero predictions occurred
301+
n_zero <- sum(near_zero, na.rm = TRUE)
301302
if (n_zero > 0) {
302303
cli::cli_warn(
303-
"Drift correction skipped for {n_zero} sample{?s} with zero predicted values."
304+
"Drift correction skipped for {n_zero} sample{?s} with near-zero predicted values."
304305
)
305306
}
306307

@@ -440,8 +441,8 @@ tidy.step_measure_drift_qc_loess <- function(x, ...) {
440441

441442
if (loc_str %in% names(models)) {
442443
predicted <- stats::predict(models[[loc_str]], newdata = run_order[i])
443-
# Guard against zero predicted values
444-
if (is.na(predicted) || predicted == 0) {
444+
# Guard against near-zero predicted values
445+
if (is.na(predicted) || abs(predicted) < sqrt(.Machine$double.eps)) {
445446
m$value[j] # No correction if predicted is zero or NA
446447
} else {
447448
correction <- medians[[loc_str]] / predicted
@@ -776,18 +777,19 @@ bake.step_measure_drift_linear <- function(object, new_data, ...) {
776777
newdata = data.frame(qc_run_order = run_order)
777778
)
778779

779-
# Calculate correction factors (guard against zero predicted values)
780+
# Calculate correction factors (guard against near-zero predicted values)
781+
near_zero <- abs(predicted) < sqrt(.Machine$double.eps)
780782
correction_factors <- ifelse(
781-
predicted == 0 | is.na(predicted),
782-
1, # No correction if predicted is zero or NA
783+
near_zero | is.na(predicted),
784+
1, # No correction if predicted is near-zero or NA
783785
qc_median / predicted
784786
)
785787

786-
# Warn if any zero predictions occurred
787-
n_zero <- sum(predicted == 0, na.rm = TRUE)
788+
# Warn if any near-zero predictions occurred
789+
n_zero <- sum(near_zero, na.rm = TRUE)
788790
if (n_zero > 0) {
789791
cli::cli_warn(
790-
"Drift correction skipped for {n_zero} sample{?s} with zero predicted values."
792+
"Drift correction skipped for {n_zero} sample{?s} with near-zero predicted values."
791793
)
792794
}
793795

@@ -1082,18 +1084,19 @@ bake.step_measure_drift_spline <- function(object, new_data, ...) {
10821084
# Predict at each run order
10831085
predicted <- stats::predict(spline_fit, x = run_order)$y
10841086

1085-
# Calculate correction factors (guard against zero predicted values)
1087+
# Calculate correction factors (guard against near-zero predicted values)
1088+
near_zero <- abs(predicted) < sqrt(.Machine$double.eps)
10861089
correction_factors <- ifelse(
1087-
predicted == 0 | is.na(predicted),
1088-
1, # No correction if predicted is zero or NA
1090+
near_zero | is.na(predicted),
1091+
1, # No correction if predicted is near-zero or NA
10891092
qc_median / predicted
10901093
)
10911094

1092-
# Warn if any zero predictions occurred
1093-
n_zero <- sum(predicted == 0, na.rm = TRUE)
1095+
# Warn if any near-zero predictions occurred
1096+
n_zero <- sum(near_zero, na.rm = TRUE)
10941097
if (n_zero > 0) {
10951098
cli::cli_warn(
1096-
"Drift correction skipped for {n_zero} sample{?s} with zero predicted values."
1099+
"Drift correction skipped for {n_zero} sample{?s} with near-zero predicted values."
10971100
)
10981101
}
10991102

R/lod-loq.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ measure_lod <- function(
9797
response_col,
9898
conc_col,
9999
calibration,
100-
k = 3.3
100+
k = k
101101
),
102102
sn = .lod_signal_noise(
103103
data,
@@ -197,7 +197,7 @@ measure_loq <- function(
197197
response_col,
198198
conc_col,
199199
calibration,
200-
k = 10
200+
k = k
201201
),
202202
sn = .lod_signal_noise(
203203
data,

_pkgdown.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ articles:
7575
desc: Information-oriented technical descriptions
7676
contents:
7777
- articles/reference-preprocessing
78-
- reference-multidimensional
79-
- reference-validation
78+
- articles/reference-multidimensional
79+
- articles/reference-validation
8080
- title: Explanation
8181
desc: Understanding-oriented discussion of concepts and architecture
8282
contents: explanation-internals

0 commit comments

Comments
 (0)