This tutorial moves from an explicit question to a saved power specification. It runs offline with the installed package. All design values are hypothetical; a subject-matter justification of the effect and sampling design remains necessary.
The advisor records explicit choices. It does not infer a study design from data. At each step, inspect the available option identifiers before answering.
session <- advisor_session()
advisor_question(session)
#> <advisor_question> q.aim (en)
#> What is the main aim of the analysis?
#> [describe] Describe variables (distributions, frequencies, summaries) without testing a hypothesis
#> [compare] Compare an outcome between groups, conditions or time points (a difference)
#> [associate] Quantify the association between two variables without designating one as the outcome
#> [model] Estimate how an outcome depends on one or more predictors, possibly adjusted for others (regression)
#> [predict] Develop a model that predicts an outcome for new individuals
#> [performance] Evaluate how well an existing score, test or classifier identifies a binary condition, or choose a cutoff
#> [structure] Explore structure without a designated outcome: summarise many variables into dimensions, or group cases
#> [causal] Estimate the causal effect of an exposure or intervention
#> [dont_know] I do not know
session <- advisor_answer(session, "compare")
advisor_question(session)
#> <advisor_question> q.stage (en)
#> Are you planning a future study or analysing data that already exist?
#> [planning] Planning a future study (sample size, power)
#> [analysis] Analysing existing data
#> [both] Both: planning a study together with its analysis plan
#> [dont_know] I do not knowThe returned session is a new object. Keep it if you want to continue
or return to an earlier answer. A partially answered session is not a
completed analysis recommendation. advisor_save() and
advisor_restore() support a longer session; review any
script from advisor_r_code() before executing it.
For the calculation below, assume two independent normal populations with equal variances, equal allocation, and a prespecified standardised mean difference of 0.5. These assumptions select the pooled-variance two-sample t procedure. They do not describe paired, clustered or unequal-variance observations.
spec <- analysis_spec(
"t_means_two_independent", "a_priori",
inputs = list(alpha = 0.05, power = 0.80, d = 0.5),
options = list(tails = "two")
)
spec
#> <power_spec> t_means_two_independent | a_priori
#> method: Means: Difference between two independent means (two groups)
#> solve for: n_total
#> inputs: d = 0.5, alpha = 0.05, power = 0.8, allocation_ratio = 1 (default)
#> options: tails = two
#> validated against: method definition
#> spec hash: b370822fcf65844eb1a72100fe306057dcb019f5da1c1c108dbe4b82fb2982c9alpha is the two-sided type-I error probability;
power is the target rejection probability under the
specified alternative. The effect size is the difference in population
means divided by their common standard deviation. An a priori
specification asks the solver for sample size, so do not also supply
n_total.
result <- solve_design(spec)
result
#> <power_result> t_means_two_independent | a_priori
#> status: ok
#> solved: n_total = 128
#> achieved: alpha_attained = 0.05; beta = 0.1985404; power = 0.8014596
#> group sizes: n1 = 64; n2 = 64
#> quantities: alpha_nominal = 0.05; critical = -1.978971, 1.978971; df = 126; ncp = 2.828427
#> validation: independently_checked; G*Power reference: reference_pending
#> spec hash: b370822fcf65844eb1a72100fe306057dcb019f5da1c1c108dbe4b82fb2982c9
stopifnot(result$status$code == "ok")
result$group_sizes
#> n1 n2
#> 64 64
result$assumptions
#> [1] "two independent samples from normal populations with equal variances (pooled-variance Student t test; G*Power offers no Welch variant)"
#> [2] "d = (mu1 - mu2) / sigma; df = n1 + n2 - 2; ncp = d * sqrt(n1 * n2 / (n1 + n2)) (manual 21.5)"
#> [3] "two-sided test: alpha/2 in each tail; the power counts both rejection tails (G*Power convention, manual 25.5)"
result$warnings
#> character(0)
result$validation
#> $documented_example_ids
#> [1] "DOC-001" "DOC-002" "DOC-003" "DOC-005" "DOC-006" "DOC-007" "DOC-008"
#> [8] "DOC-009" "DOC-010" "DOC-011" "DOC-012" "DOC-013" "DOC-014" "DOC-015"
#> [15] "DOC-016" "DOC-017" "DOC-098" "DOC-099"
#>
#> $fixture_ids
#> character(0)
#>
#> $gpower_reference_status
#> [1] "reference_pending"
#>
#> $independent_checker
#> [1] "validation/independent/t/check_t_means_two_independent.R"
#>
#> $method_validation_status
#> [1] "independently_checked"solved$n_total is the combined sample size;
group_sizes gives the allocation.
achieved$power can exceed the target because only
admissible integer designs are considered. The ok
calculation status and the method’s reference-validation status answer
different questions. Neither establishes clinical utility or correct
study assumptions.
Constructor errors and numerical outcomes are distinct. Here the error is expected because a probability is outside its domain.
problem <- tryCatch(
analysis_spec("t_means_two_independent", "a_priori",
inputs = list(alpha = 1.5, power = 0.8, d = 0.5)),
error = function(e) conditionMessage(e)
)
problem
#> [1] "invalid specification for t_means_two_independent (a_priori): 'alpha' must lie in (0, 1) (got 1.5)"
stopifnot(is.character(problem))For other analysis modes use calculate_power(). Inspect
?analysis_spec for mode-specific targets and
list_methods() for available procedures; a registry entry
alone does not establish that a numerical engine is implemented.
path <- tempfile(fileext = ".json")
writeLines(ig_to_json(spec), path)
restored <- ig_from_json(file = path)
stopifnot(identical(ig_hash(spec), ig_hash(restored)))
replayed <- solve_design(restored)
stopifnot(identical(result$solved, replayed$solved))Save the result as well as its specification when archiving an analysis. Record the package revision and execution environment: a matching content hash proves identity of that content, not scientific validation across software versions.
The classification tutorial introduces denominators and explicit operating points. To explore the same public functions interactively:
The launch chunk is not evaluated during a documentation build because it starts an interactive server. No external reference application is required.
sessionInfo()
#> R version 4.6.2 (2026-10-29)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] inferguidR_0.0.0.9000 rmarkdown_2.32
#>
#> loaded via a namespace (and not attached):
#> [1] digest_0.6.39 R6_2.6.1 fastmap_1.2.0 xfun_0.62
#> [5] maketools_1.3.2 cachem_1.1.0 knitr_1.52 htmltools_0.5.9
#> [9] buildtools_1.0.0 lifecycle_1.0.5 cli_3.6.6 jsonvalidate_1.5.0
#> [13] sass_0.4.10 jquerylib_0.1.4 compiler_4.6.2 sys_3.4.3
#> [17] tools_4.6.2 curl_8.1.0 evaluate_1.0.5 bslib_0.12.0
#> [21] Rcpp_1.1.2 yaml_2.3.12 otel_0.2.0 V8_8.2.1
#> [25] jsonlite_2.0.0 rlang_1.3.0