Power workshop
Week 6: curves, assumptions and design recommendations
Gavin Simpson
Aarhus University
Wednesday, 7 October 2026
Workshop route
13:55–14:15
Repetition and one sample size
14:15–14:40
Build or open the baseline curve
14:40–14:55
Interpret the curve and null reference
14:55–15:10
Break
15:10–15:25
Reports and assumptions
15:25–15:40
Recommendation and sensitivity prediction
15:40–15:55
Group project briefing
15:55–16:00
Individual exit
The foundational deck handles the first part of the worksheet before the break. Resume at script section 3. Do not run a second curve in class. The student worksheet is the continuous record.
Rotate roles
Driver: run the code.
Model translator: explain what is being simulated and tested.
Design auditor: check units, assumptions and unresolved results.
Rotate now, and again at 15:10.
13:55. Driver becomes model translator, model translator becomes auditor, auditor becomes driver. Ask for a verbal prediction before the driver runs code.
Twenty repeated experiments
run_simulations() repeats generation, fitting and the test. small has one row per attempted experiment.
small <- run_simulations (s, total_pens = 16 ,
B = 20 , seed = 6203 )
small |> slice (1 : 10 ) |>
select (iteration, detected) |>
print (n = 10 )
# A tibble: 10 × 2
iteration detected
<int> <lgl>
1 1 TRUE
2 2 TRUE
3 3 FALSE
4 4 FALSE
5 5 FALSE
6 6 FALSE
7 7 TRUE
8 8 FALSE
9 9 TRUE
10 10 FALSE
small |> slice (11 : 20 ) |>
select (iteration, detected) |>
print (n = 10 )
# A tibble: 10 × 2
iteration detected
<int> <lgl>
1 11 FALSE
2 12 TRUE
3 13 FALSE
4 14 FALSE
5 15 FALSE
6 16 TRUE
7 17 FALSE
8 18 FALSE
9 19 TRUE
10 20 FALSE
Count TRUE across all 20 attempts before advancing.
13:55–14:05. Each row represents a complete 16-pen experiment. The split shows all 20 decisions without truncation. An unresolved attempt is FALSE for detection and remains in the denominator. Do not set an identical seed inside each repetition.
From decisions to a proportion
First count detections directly. Then use summarise_runs() to count unresolved analyses and calculate a Monte Carlo interval.
sum (small$ detected) / nrow (small)
small_summary <- summarise_runs (small)
small_summary |>
select (attempted, detections, unresolved, detection, lower, upper)
# A tibble: 1 × 6
attempted detections unresolved detection lower upper
<int> <int> <int> <dbl> <dbl> <dbl>
1 20 7 0 0.35 0.181 0.567
Twenty repetitions give a rough illustration, not a stable recommendation.
Estimate at 16 pens
Create one_size using the same design and assumptions, with 200 repetitions.
one_size <- run_simulations (s, total_pens = 16 ,
B = 200 , seed = 6303 )
one_summary <- summarise_runs (one_size)
one_summary |>
select (attempted, detections, unresolved, detection, lower, upper)
# A tibble: 1 × 6
attempted detections unresolved detection lower upper
<int> <int> <int> <dbl> <dbl> <dbl>
1 200 61 2 0.305 0.245 0.372
Compare with 20 repetitions. What became more precise? What stayed the same?
14:05–14:15. Keep B distinct from total_pens. These are new simulated repetitions, not extra pens. The selected columns show counts, the detection proportion and interval; the full summary remains available in one_summary.
Reading the summary
attempted
All simulated experiments
detections
Results passing numerical screens with p < 0.05
unresolved
Attempts not suitable for the declared test decision
detection
Detections / all attempts
lower, upper
95% Monte Carlo interval
An unresolved result stays in the denominator.
The intervals are Wilson intervals for the operational binary detection event. They quantify simulation noise, not biological parameter uncertainty. A high unresolved fraction is a limitation to discuss separately.
Four candidate designs
16
4
8
32
8
16
48
12
24
64
16
32
Four rooms and six pigs per pen remain fixed. More room capacity must be justified before adopting a larger design.
14:15. Adding rooms would need assumptions about additional room effects. Adding pigs within existing pens does not add independent diet assignments. Balanced allocation is retained at every size.
Build your curve
run_curve() repeats the calculation at each requested size. Combine other_sizes with the existing 16-pen one_size results.
other_sizes <- run_curve (s, sizes = c (32 , 48 , 64 ),
B = 200 , seed = 6403 )
baseline_runs <- bind_rows (one_size, other_sizes)
baseline_summary <- summarise_runs (baseline_runs)
baseline_summary |>
select (total_pens, detection, unresolved_rate, lower, upper)
# A tibble: 4 × 5
total_pens detection unresolved_rate lower upper
<dbl> <dbl> <dbl> <dbl> <dbl>
1 16 0.305 0.01 0.245 0.372
2 32 0.575 0.005 0.506 0.641
3 48 0.775 0.005 0.712 0.827
4 64 0.86 0 0.805 0.901
These proportions and intervals describe the baseline assumptions.
14:15–14:40. Reuse the 16-pen batch. Stop computing at 14:40 and use supplied results if needed. Every size retains four rooms with balanced diets. The summary is a new table, distinct from the per-experiment baseline_runs.
Plot the baseline results
plot_curve() plots detection with its Monte Carlo interval against total_pens.
plot_curve (baseline_summary)
Read the unresolved rates on the preceding slide alongside this curve.
Interpret before recommending
What does a point on the curve estimate?
Why might adjacent exploratory points be irregular?
What uncertainty do the error bars include?
Which tested sizes support an 80% target?
What if no size reaches it?
Do not invent a minimum sample size between four simulated points.
14:40–14:50. Expected: conditional operational detection probability, Monte Carlo noise, simulation uncertainty only, qualified comparison with target. No crossing is an acceptable answer. Near-threshold points require more simulations and assumptions review.
Load the reference results
reference/power-summary.csv contains the supplied 2,000-repetition results. Read it into reference, then select Group 3’s baseline, nonzero-effect rows.
reference <- read_csv ("reference/power-summary.csv" ,
show_col_types = FALSE )
reference |>
filter (group == s$ group, scenario == "Baseline" , ! null) |>
select (total_pens, attempted, detection, unresolved_rate)
# A tibble: 4 × 4
total_pens attempted detection unresolved_rate
<dbl> <dbl> <dbl> <dbl>
1 16 2000 0.311 0.0065
2 32 2000 0.574 0
3 48 2000 0.738 0.0005
4 64 2000 0.856 0
Compare with your 200-repetition results. Use these supplied results if live computation is slow.
Check the no-effect scenario
The rows with null == TRUE set the generating diet effect to zero, keeping baseline, room effects and variation.
reference |>
filter (group == s$ group, scenario == "Baseline" , null) |>
select (total_pens, detection, unresolved_rate, lower, upper)
# A tibble: 4 × 5
total_pens detection unresolved_rate lower upper
<dbl> <dbl> <dbl> <dbl> <dbl>
1 16 0.0485 0.018 0.0399 0.0588
2 32 0.048 0.011 0.0395 0.0583
3 48 0.0515 0.009 0.0426 0.0621
4 64 0.0465 0.0085 0.0381 0.0566
Here detection estimates false-positive frequency , not power under a nonzero effect. Compare with the nominal 5% rate.
14:50–14:55. Use supplied results only. Sampling variation, approximations and numerical screening can affect null rejection. Do not require every interval to include 0.05. No new null simulation is assigned.
Two-minute reports
Each group reports:
the response and effect scale
the assumed effect and one uncertain assumption
one curve finding, with its limitation
one credible design or measurement improvement
These outcomes answer different scientific questions. A higher curve does not automatically make an outcome a better choice.
15:10–15:25: two minutes each plus transitions. Include the conditional recommendation, baseline finding, independent-unit count and limitation. Example alternatives: reduce unexplained variation, improve measurement precision, preserve balance and account for room. These need plausible mechanisms and cannot be asserted to have a known gain without simulation. The appendix precision slides are optional follow-up material; skip them in class to preserve the project briefing.
Your conditional recommendation
“Under [generator and parameters], with [design and analysis], the estimated probability of [testing event] at [total pens; pens per diet] is [estimate and interval].
This uses [repetitions] with [unresolved proportion]. We recommend [design or further investigation], conditional on [feasibility and uncertain assumptions].”
Write this after the reports. Save the baseline results with script section 6.
15:25–15:35. Write the recommendation, then make the sensitivity prediction. Include independent replication and one feasible design/measurement lever. No tested size adequate is valid. Do not extrapolate beyond the grid or treat 80% as universal. The written peer-swap is optional later rather than another classroom block.
Predict a change to your power curve
Imagine repeating the power calculation at the same sample sizes, after making your group’s change to the data generating process:
Gaussian
Increase SD from 60 to 90 g/day
Binary
Reduce Room 1 control probability from 0.30 to 0.15
Poisson
Reduce Room 1 control mean from 3 to 1.5 events
Gamma
Reduce shape from 25 to 9; keep means fixed
Would you expect your curve to move up, move down, or stay similar? Why?
Predict now; do not run another curve in class.
15:35–15:40 across these two slides. Introduce the specific changes before asking students to predict. Each comparison changes one input to the data generating process and repeats the same power procedure. Gaussian SD rises with unchanged means. Binary and Poisson baselines fall while their ratio effects stay fixed. For Gamma, reducing shape increases variation; scale is recalculated as mean/shape to keep means fixed. Do not reveal the reference sensitivity curve before students record a reasoned prediction.
What stays fixed in this comparison?
For your group’s change, retain:
the diet-effect coefficient and room contrasts
the sample sizes, four-room design and balanced diet allocation
the analysis, numerical checks and detection rule
Explain how the changed assumption affects the observations and the chance of detecting the diet effect. A fixed ratio need not mean a fixed difference on the response scale.
Save your prediction. During autumn-break revision, compare the supplied Baseline and Sensitivity results for your group at the same total pens . No new simulation is required.
Finish the prediction within the existing 15:35–15:40 block. The Gaussian difference stays +45 g/day; the binary odds ratio stays 0.60; the Poisson count ratio stays 0.65; the Gamma expected-response ratio stays 0.92. Room contrasts are held fixed on the link scale; changing the intercept can change expected outcomes in every room. Ask for an explanation of the changed data generating process, not just a guess about line direction. Students revisit their prediction in the existing 10-minute sensitivity comparison within the capped revision assignment. Do not replace the assumed diet effect with a fitted estimate.
After class and Week 7
Complete the week 42 revision and project-scoping task : at most 2½ hours per student , including Unit 6 consolidation.
It replaces the separate 60-minute assignment. The 30-minute revision block includes the supplied sensitivity comparison. No new model fitting.
Week 7 meets 21 October . Bring your project brief, model map and one question.
Covered in the project briefing deck at 15:40–15:55. Read the consolidation deck for revision when a recording is unavailable. The worksheet in the student project folder is optional further practice, not an additional compulsory hour.
Individual exit question
A group reports that 32 pens give 80% power and proposes increasing the simulation count to improve the experiment.
What information is missing? What would increasing the simulation count actually improve?
15:55–16:00, after the project briefing. Require assumed effect and data generating process, allocation, analysis, criterion and independent units. Credit simulation count, MC uncertainty and unresolved fraction. Increasing B improves numerical precision but adds no real pens and changes no underlying experimental power.
Optional: compute the sensitivity curve
After class only: create s_changed with the assigned sensitivity assumption. For Group 3, Room 1’s control mean changes from 3 to 1.5; the count ratio remains 0.65.
s_changed <- scenario (3 , sensitivity = TRUE )
changed_runs <- run_curve (s_changed, B = 200 , seed = 6503 )
comparison <- bind_rows (baseline_summary,
summarise_runs (changed_runs))
comparison |>
select (scenario, total_pens, detection, unresolved_rate)
# A tibble: 8 × 4
scenario total_pens detection unresolved_rate
<chr> <dbl> <dbl> <dbl>
1 Baseline 16 0.305 0.01
2 Baseline 32 0.575 0.005
3 Baseline 48 0.775 0.005
4 Baseline 64 0.86 0
5 Sensitivity 16 0.16 0.025
6 Sensitivity 32 0.315 0.01
7 Sensitivity 48 0.445 0
8 Sensitivity 64 0.63 0
The required follow-up uses supplied results; running this code is optional.
The deck executes this appendix for reproducibility. The downloadable demonstration script and group scripts disable optional computation by default. changed_runs matches the object name in the group scripts. comparison combines summaries, not individual simulated datasets.
Optional: compare the curves
The same plotting helper can show both scenarios from comparison.
Explain the changed assumption before interpreting the separation between lines.
Detection and precision
A second planning question asks whether the effect can be estimated sufficiently precisely.
For Gaussian gain, consider a 95% interval with total width at most 60 g/day . This is an illustrative target, not a biological standard.
An interval can be narrow yet contain zero. It can exclude zero yet be too wide for a useful decision.
Optional consolidation extension. Use reference/precision-summary.csv to compare this event with detection at each size. The total width is twice the half-width. Label its probability precision success, not hypothesis-test power. Do not add this to the capped week 42 assignment.
Gaussian precision comparison
Read the supplied Gaussian results into precision. Both columns below are proportions of the same 2,000 attempts.
precision <- read_csv ("reference/precision-summary.csv" ,
show_col_types = FALSE )
precision |>
transmute (total_pens, detection = detections / attempted,
precision_success = probability_precision)
# A tibble: 4 × 3
total_pens detection precision_success
<dbl> <dbl> <dbl>
1 16 0.280 0.0025
2 32 0.545 0.009
3 48 0.722 0.11
4 64 0.822 0.522
Precision means a 95% interval at most 60 g/day wide . The two columns count different events in the same 2,000 simulations.
Optional extension; skip during the 7 October class. Source: reference/precision-summary.csv, using baseline Gaussian runs and the supplied F/t analysis. Threshold is illustrative, not scientifically validated. More precision does not require rejecting a null hypothesis.
Group 1: reference curve
2,000 repetitions per point. Display after students make their sensitivity prediction, or use for rescue. These are simulated teaching scenarios, not empirical study results. Read the unresolved proportion from the reference summary alongside this curve. Each point uses four fixed rooms and one balanced allocation. Source: instructor/build-reference.R and reference/power-summary.csv.
Group 2: reference curve
2,000 repetitions per point. Display after students make their sensitivity prediction, or use for rescue. These are simulated teaching scenarios, not empirical study results. Read the unresolved proportion from the reference summary alongside this curve. Each point uses four fixed rooms and one balanced allocation. Source: instructor/build-reference.R and reference/power-summary.csv.
Group 3: reference curve
2,000 repetitions per point. Display after students make their sensitivity prediction, or use for rescue. These are simulated teaching scenarios, not empirical study results. Read the unresolved proportion from the reference summary alongside this curve. Each point uses four fixed rooms and one balanced allocation. Source: instructor/build-reference.R and reference/power-summary.csv.
Group 4: reference curve
2,000 repetitions per point. Display after students make their sensitivity prediction, or use for rescue. These are simulated teaching scenarios, not empirical study results. Read the unresolved proportion from the reference summary alongside this curve. Each point uses four fixed rooms and one balanced allocation. Source: instructor/build-reference.R and reference/power-summary.csv.
Sources
Reference curves are generated from the supplied teaching scenarios.
All reference counts and probabilities are reproducible using the instructor build script. The student handout explains denominator handling. No textbook reading is assigned.