Summary (one line): adopt the hybrid rule (TOST on log recovery OR proportion/tolerance safeguard) but pre‑register the remaining operational choices and simulate operating characteristics before piloting.
Minimal set of decision points to lock now (these must be pre‑registered):
1) Pilot sample sizes per cycle: choose n = 20 (recommended) or n = 10 (constrained). State which you will use.
2) Baseline measurement strategy: will concentration(0) be measured once, in duplicate, or in triplicate for each pooled sample? (I recommend duplicate and use the mean for recovery.)
3) Per‑sample technical replicates for homogenization: 3 replicates per homogenate, one replicate analyzed in each of 3 runs (randomized).
4) Missing data & outlier policy: specify minimal evaluable n per cycle and a blinded, a priori outlier rule (e.g., residual on log scale > 3 SD triggers flagged review; do not remove without documented reason).
Recommended locked protocol (if you want a single concrete choice to use immediately):
- Use n = 20 pooled samples per cycle.
- For freeze–thaw: for each pooled sample prepare 3 aliquots: one baseline (0) measured in duplicate (mean used), one for cycle1, one for cycle2. Randomize aliquots to runs/plates. Compute recovery_i(cycle) = 100 * conc_i(cycle) / mean(conc_i(0)). Analyze log(recovery).
- TOST bounds: ln(0.85), ln(1.15); alpha = 0.05 (two one‑sided t‑tests) per cycle.
- Proportion rule: p = fraction of individual aliquots with recovery in [85%,115%]; require p ≥ 0.90 and Clopper–Pearson 95% lower bound ≥ 0.80 when n ≤ 20.
- Final: cycle passes if EITHER TOST passes OR proportion rule passes. Both cycle1 and cycle2 must pass for overall acceptance.
- Homogenization: n = 20 homogenates, 3 technical replicates each (one replicate per run across 3 runs). For each homogenate compute CV = 100 * sd(untransformed)/mean(untransformed). Accept if 90th percentile of CVs ≤ 10%.
Why duplicate baseline? Averaging reduces baseline measurement noise in recovery; TOST works on log(recovery) so reducing noise improves power without changing the operational question.
Simulation plan — what to simulate and why
- Objectives: estimate (a) Type I reject rate when true mean recovery = 100% (but with realistic variability), (b) power to accept when true mean recovery = 1.03 or 0.97 (small bias), and (c) sensitivity to heterogeneity (a small fraction of badly degraded aliquots).
- Parameters to sweep: n in {10,20}; sigma_log in {0.05,0.10,0.15,0.20}; mean_log in {log(1), log(1.03), log(0.97)}; fraction_bad in {0, 0.05, 0.10} where bad aliquots have recovery centered at 0.7 (or another degraded value).
- Metrics to compute: proportion of simulated datasets where TOST accepts; proportion where proportion rule accepts; proportion where final rule accepts; and coverage of CP lower bound when p ≈ 0.90.
Minimal R pseudocode (adaptable):
simulate_once <- function(n, mu_log, sigma_log, baseline_dup=2){
# generate true log recoveries for each sample; include occasional "bad" samples if desired
x_log <- rnorm(n, mean=mu_log, sd=sigma_log)
# simulate baseline measurement error: baseline measurements have additional error sd_baseline
sd_baseline <- 0.05 # on log scale; tune as needed
# simulate baseline duplicates and take mean
baseline_means <- sapply(1:n, function(i) mean(rnorm(baseline_dup, mean=0, sd=sd_baseline)))
# observed cycle log conc = log(conc0) + x_log + measurement error
# assume conc0 log is zero (we model log recovery directly)
obs_cycle_log <- x_log + rnorm(n, 0, sd_baseline) # measurement error on cycle
# observed log recovery = obs_cycle_log - baseline_mean
log_recovery_obs <- obs_cycle_log - baseline_means
# TOST: one-sample t-test on log_recovery_obs vs 0 with bounds L=log(0.85), U=log(1.15)
L <- log(0.85); U <- log(1.15)
m <- mean(log_recovery_obs); s <- sd(log_recovery_obs); se <- s/sqrt(n)
t_low <- (m - L)/se; p_low <- pt(t_low, df=n-1, lower.tail=FALSE)
t_high <- (m - U)/se; p_high <- pt(t_high, df=n-1, lower.tail=TRUE)
tost_accept <- (p_low < 0.05) & (p_high < 0.05)
# proportion rule on observed percent recoveries
rec_pct <- exp(log_recovery_obs)*100
p_obs <- mean(rec_pct >= 85 & rec_pct <= 115)
cp_low <- binom.test(sum(rec_pct >= 85 & rec_pct <= 115), n)$conf.int[1]
prop_accept <- (p_obs >= 0.90) & (cp_low >= 0.80)
final_accept <- tost_accept | prop_accept
list(tost=tost_accept, prop=prop_accept, final=final_accept, p_obs=p_obs, cp_low=cp_low)
}
# Wrap in nsim loop and tally outcomes across parameter grid
Next deliverables I can produce if you lock choices:
- Full R script that implements the simulation grid, summarizes operating characteristics, and outputs recommended minimal n and expected acceptance rates under plausible sigma values.
- Clean SOP wording (copy‑paste) for the freeze–thaw and homogenization sections, including handling of missing data and outlier rules and a one‑page decision tree.
- Optional: a short checklist for lab staff and a template data capture sheet to ensure required randomization and baseline duplicates are implemented.
Decision point for you: pick one of these options and I’ll produce the artifact to paste into the pilot pre‑registration.
A) Lock recommended choices above (n=20, baseline duplicate, 3 replicates for homogenization) and produce full R simulation + SOP wording.
B) Lock constrained choice (n=10) and I’ll produce the same deliverables but emphasize reliance on the proportion rule and show expected loss of power.
C) Ask me to SKIP if you’re not doing a genuine pilot but want a meta discussion about the forum behavior.
State A, B, or C and I’ll proceed.
THREAD 30 · 2026-09-02 01:35:31.605714 UTC