| Type: | Package |
| Title: | A Tidyverse-First Research Design Declaration and Diagnosis Tool |
| Version: | 2.0.0 |
| Description: | Declares, simulates, diagnoses and redesigns research designs. A design is declared as a model, an inquiry, a data strategy and an answer strategy, then simulated with 'purrr' and diagnosed with 'dplyr'. Version 2.0 is a ground-up rewrite of the package on tidyverse conventions. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.1.0), randomizr (≥ 1.0.1), fabricatr (≥ 2.0.0), estimatr (≥ 2.0.0) |
| Imports: | broom, dplyr, generics, parallel, purrr, rlang, tibble, tidyr, utils |
| Suggests: | furrr, future, knitr, MASS, progressr, rmarkdown, testthat (≥ 3.0.0), withr |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.0.0 |
| URL: | https://declaredesign.org/r/declaredesign/, https://github.com/DeclareDesign/DeclareDesign |
| BugReports: | https://github.com/DeclareDesign/DeclareDesign/issues |
| NeedsCompilation: | no |
| Packaged: | 2026-10-24 15:20:08 UTC; alexandercoppock |
| Author: | Alexander Coppock |
| Maintainer: | Alexander Coppock <acoppock@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-25 14:30:36 UTC |
DeclareDesign: A Tidyverse-First Research Design Declaration and Diagnosis Tool
Description
Declares, simulates, diagnoses and redesigns research designs. A design is declared as a model, an inquiry, a data strategy and an answer strategy, then simulated with purrr and diagnosed with dplyr. Version 2.0 is a ground-up rewrite of the package on tidyverse conventions.
Details
A design is a sequence of steps combined with +. Each step is one of the
four elements of a research design:
-
declare_model()describes the world the design runs in. -
declare_inquiry()records the question. Its value on a draw is the estimand. -
declare_sampling(),declare_assignment(), anddeclare_measurement()make up the data strategy: who is observed, what they are assigned, and what is measured. -
declare_estimator()anddeclare_test()are the answer strategy.
diagnose_design() simulates a design many times and reports how its
estimates compare to its estimands: bias, power, coverage, and the rest.
redesign() changes a parameter and returns a new design, so two versions
can be compared before any data are collected.
design <- declare_model(N = 100, U = rnorm(N), Y_Z_0 = U, Y_Z_1 = U + 0.5) + declare_inquiry(ATE = mean(Y_Z_1 - Y_Z_0)) + declare_assignment(Z = sample(rep(0:1, length.out = N))) + declare_measurement(Y = Y_Z_0 * (1 - Z) + Y_Z_1 * Z) + declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE") diagnose_design(design)
Author(s)
Maintainer: Alexander Coppock acoppock@gmail.com (ORCID)
Authors:
Alexander Coppock acoppock@gmail.com (ORCID)
Graeme Blair graeme.blair@gmail.com (ORCID)
Jasper Cooper jaspercooper@gmail.com (ORCID)
Macartan Humphreys macartan@gmail.com (ORCID)
Neal Fultz nfultz@gmail.com
See Also
Useful links:
Report bugs at https://github.com/DeclareDesign/DeclareDesign/issues
Combine design steps into a design
Description
The + operator concatenates design_step and design objects into a
single design. design + NULL is a no-op that returns the design
unchanged, which makes conditional step addition convenient.
Usage
## S3 method for class 'dd'
e1 + e2
Arguments
e1 |
(required) A |
e2 |
(required) A |
Value
A design (class c("design", "dd")): a list of the steps of
e1 followed by those of e2, named by their labels.
Examples
d <- declare_model(N = 50, U = rnorm(N), Y = U) +
declare_inquiry(mu = mean(Y))
length(d)
Retrieve a design's citation
Description
Returns the citation set_citation() attached to the design, or, when
none was attached, the citation for the DeclareDesign package itself.
Usage
cite_design(design)
Arguments
design |
(required) A |
Value
The design's citation, a bibentry or a string, or
utils::citation("DeclareDesign") when none has been set.
See Also
Other citing a design:
set_citation()
Examples
design <- set_citation(declare_model(N = 10, Y = rnorm(N)),
title = "Example", author = "Coppock", year = 2026)
cite_design(design)
Defunct comparison helpers
Description
These functions existed in DeclareDesign 1.x but are not part of 2.0. Each compared two designs by printing their code, their draws, or their summaries side by side, which is a job for a diff of the two scripts. They error with a message saying so.
Usage
compare_designs(...)
compare_design_code(...)
compare_design_data(...)
compare_design_estimates(...)
compare_design_inquiries(...)
compare_design_summaries(...)
print_code(...)
Arguments
... |
(optional) Ignored. |
Details
compare_diagnoses(), which compares what two designs achieve rather than
how they are written, is implemented.
Value
Never returns; always raises an error.
Compare the diagnosands of two designs
Description
Diagnoses both designs and reports, for every diagnosand they have in common, the value under each design and the difference between them. The bootstrap replicates behind each diagnosis supply a standard error and a confidence interval for the difference.
Usage
compare_diagnoses(
design1,
design2,
sims = 500,
bootstrap_sims = 100,
diagnosands = NULL,
merge_by_estimator = TRUE,
alpha = 0.05
)
Arguments
design1, design2 |
(required) A |
sims |
(optional) Number of simulations, used only for arguments that
are designs. Defaults to |
bootstrap_sims |
(optional) Number of bootstrap replicates, used only
for arguments that are designs. Defaults to |
diagnosands |
(optional) A diagnosands |
merge_by_estimator |
(optional) Match estimators by label. |
alpha |
(optional) One minus the coverage of the reported interval.
Defaults to |
Details
Rows are matched on whichever of inquiry, estimator, and term both
diagnoses carry. With merge_by_estimator = FALSE, estimators are not
matched to each other and every pair within an inquiry is compared, which
is how to compare two estimators that carry different labels.
mean_difference is the difference of the two point estimates. The
bootstrap enters only through se_difference and the interval. The two
designs are simulated independently, so the replicates are paired
arbitrarily; the interval is a percentile interval on that difference.
Either argument may be a design or an already computed diagnosis, so a
diagnosis that took a long time to run can be reused. Passing two diagnoses
computed with different diagnosands compares whatever they have in common.
Value
A compared_diagnoses object: a list with three elements.
compared_diagnoses_df is a tibble with one row per diagnosand per
matched group, holding the grouping columns, diagnosand, mean_1,
mean_2, mean_difference, se_1, se_2, se_difference, conf.low,
and conf.high (the last four are NA without bootstrap replicates).
diagnosis1 and diagnosis2 are the two diagnosis
objects compared.
See Also
Other simulation and diagnosis:
diagnose_design(),
diagnose_simulations(),
get_diagnosands(),
get_simulations(),
simulate_design()
Examples
design <- declare_parameters(n_units = 100) +
declare_model(N = n_units, U = rnorm(N), Y_Z_0 = U, Y_Z_1 = U + 0.5) +
declare_inquiry(ATE = mean(Y_Z_1 - Y_Z_0)) +
declare_assignment(Z = randomizr::complete_ra(N)) +
declare_measurement(Y = Y_Z_1 * Z + Y_Z_0 * (1 - Z)) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
bigger <- redesign(design, n_units = 200)
compare_diagnoses(design, bigger, sims = 20, bootstrap_sims = 20)
Defunct step declarations from DeclareDesign 1.x
Description
declare_potential_outcomes() and declare_reveal() were separate steps in
1.x. In 2.0 potential outcomes belong in declare_model() and revealing
belongs in declare_measurement(), so neither has a 2.0 equivalent as a
step of its own.
Usage
declare_potential_outcomes(...)
declare_reveal(...)
Arguments
... |
(optional) Ignored. |
Details
They exist here only so that 1.x code fails with a message saying what to
write instead. Without them R reports could not find function, which says
nothing about the replacement.
Value
Never returns; always raises an error.
Declare an assignment procedure
Description
Assigns units to treatment conditions, adding the assignment variable (Z
by convention) to the data. The randomization itself is usually a randomizr
function such as randomizr::complete_ra().
Usage
declare_assignment(..., label = "assignment", draws = 1L)
Arguments
... |
(optional) Named arguments forwarded to
|
label |
(optional) Step label. Defaults to |
draws |
(optional) Number of nested draws for this step. Defaults to
|
Value
A design_step (class c("design_step", "dd", "function")): a
function that takes the current data frame and returns it with the
declared columns added. Add it to a design with +.
See Also
Other design declarations:
declare_estimator(),
declare_inquiry(),
declare_measurement(),
declare_model(),
declare_notes(),
declare_parameters(),
declare_sampling(),
declare_step(),
declare_test()
Examples
design <-
declare_model(N = 100, U = rnorm(N)) +
declare_assignment(Z = sample(rep(0:1, length.out = N)))
table(draw_data(design)$Z)
Declare diagnosands
Description
Defines the summary statistics computed across simulations during
diagnosis. Each named expression is evaluated against the simulations
data frame, grouped by inquiry, estimator, term, and outcome
where present.
Usage
declare_diagnosands(..., subset = NULL, alpha = 0.05, label = "diagnosands")
Arguments
... |
(optional) Named expressions defining diagnosands, each evaluated on the simulations table of one group and returning a single value. |
subset |
(optional) An expression evaluated on the simulations table;
only rows for which it is |
alpha |
(optional) Significance level. Any diagnosand expression that
mentions |
label |
(optional) Step label. Defaults to |
Value
A diagnosands design_step: a function that takes a simulations
table and returns a tibble with columns diagnosand and value, one row
per diagnosand. Its dots attribute carries the diagnosand quosures. Pass
it to diagnose_design() as diagnosands.
See Also
Other diagnosands:
default_diagnosands(),
format.diagnosis(),
select_diagnosands(),
set_diagnosands()
Examples
diags <- declare_diagnosands(
bias = mean(estimate - estimand, na.rm = TRUE),
rmse = sqrt(mean((estimate - estimand)^2, na.rm = TRUE))
)
design <-
declare_model(N = 30, U = rnorm(N), Y_Z_0 = U, Y_Z_1 = U + 0.5) +
declare_inquiry(ATE = mean(Y_Z_1 - Y_Z_0)) +
declare_assignment(Z = sample(rep(0:1, length.out = N))) +
declare_measurement(Y = Y_Z_0 * (1 - Z) + Y_Z_1 * Z) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE")
diagnose_design(design, sims = 5, bootstrap_sims = 0, diagnosands = diags)
# power at the 10 percent level, computed on significant simulations only
declare_diagnosands(power = mean(p.value <= alpha), alpha = 0.1)
Declare an estimator
Description
Declares the answer strategy: a function that produces an estimate of an
inquiry from the observed data. The estimate is tidied to one row per term
and joined to its estimand by the inquiry label during diagnosis.
Usage
declare_estimator(
...,
.method = NULL,
.summary = tidy_try,
inquiry = NULL,
term = NULL,
label = "estimator",
handler = NULL,
draws = 1L
)
Arguments
... |
(optional) Arguments forwarded, as written, to |
.method |
(optional) The model-fitting function. Defaults to
|
.summary |
(optional) Function used to tidy |
inquiry |
(optional) The label of the inquiry this estimator targets,
as a string ( |
term |
(optional) Which model terms to report. A character vector keeps
exactly those terms, in that order, and errors if any is absent from the
tidied output; |
label |
(optional) Step label. Defaults to |
handler |
(optional) A function. When supplied, the estimator bypasses
|
draws |
(optional) Number of nested draws for this step. Defaults to
|
Value
A design_step (class c("design_step", "dd", "function")): a
function that takes a data frame and returns a tibble of estimates, one
row per reported term, with estimator and, when inquiry is set,
inquiry columns. A draw on which .method errors returns a row with
error = TRUE and the message rather than stopping the run. Add it to a
design with +.
See Also
Other design declarations:
declare_assignment(),
declare_inquiry(),
declare_measurement(),
declare_model(),
declare_notes(),
declare_parameters(),
declare_sampling(),
declare_step(),
declare_test()
Examples
design <- declare_model(N = 50, U = rnorm(N), Y = U) +
declare_inquiry(mu = mean(Y)) +
declare_estimator(Y ~ 1, .method = lm, term = "(Intercept)",
inquiry = "mu", label = "ols")
draw_estimates(design)
Declare an inquiry
Description
Each named argument records an inquiry: an expression evaluated on the data as it stands when the step runs. Its value on a given draw is the estimand.
Usage
declare_inquiry(
...,
subset = NULL,
label = "inquiry",
handler = NULL,
draws = 1L
)
declare_inquiries(
...,
subset = NULL,
label = "inquiry",
handler = NULL,
draws = 1L
)
declare_estimand(
...,
subset = NULL,
label = "inquiry",
handler = NULL,
draws = 1L
)
declare_estimands(
...,
subset = NULL,
label = "inquiry",
handler = NULL,
draws = 1L
)
Arguments
... |
(optional) Named expressions. Each expression becomes an inquiry
whose numeric value is recorded in the simulation output. An unnamed
expression takes the step's |
subset |
(optional) Unquoted expression evaluated on the data; only
rows where it is |
label |
(optional) Step label. Defaults to |
handler |
(optional) A function. When supplied, |
draws |
(optional) Number of nested draws for this step. Defaults to
|
Value
A design_step (class c("design_step", "dd", "function")): a
function that takes a data frame and returns a tibble with columns
inquiry and estimand, one row per inquiry. Add it to a design with
+.
See Also
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_measurement(),
declare_model(),
declare_notes(),
declare_parameters(),
declare_sampling(),
declare_step(),
declare_test()
Examples
design <-
declare_model(N = 100, U = rnorm(N), Y_Z_0 = U, Y_Z_1 = U + 0.5) +
declare_inquiry(ATE = mean(Y_Z_1 - Y_Z_0))
draw_estimands(design)
# Placed before declare_sampling(), the question is about the population;
# placed after, about the sample.
design <-
declare_model(N = 500, Y = rnorm(N)) +
declare_inquiry(population_mean = mean(Y)) +
declare_sampling(S = sample(rep(0:1, length.out = N))) +
declare_inquiry(sample_mean = mean(Y))
draw_estimands(design)
Declare measurement
Description
Records what the study observes: the measured outcome, typically Y
revealed from the potential outcomes given the assignment Z. Columns are
added to the data the way declare_model() adds them, without a new ID
column.
Usage
declare_measurement(..., label = "measurement", draws = 1L)
Arguments
... |
(optional) Named arguments forwarded to
|
label |
(optional) Step label. Defaults to |
draws |
(optional) Number of nested draws for this step. Defaults to
|
Value
A design_step (class c("design_step", "dd", "function")): a
function that takes the current data frame and returns it with the
declared columns added. Add it to a design with +.
See Also
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_inquiry(),
declare_model(),
declare_notes(),
declare_parameters(),
declare_sampling(),
declare_step(),
declare_test()
Examples
design <-
declare_model(N = 100, U = rnorm(N), Y_Z_0 = U, Y_Z_1 = U + 0.5) +
declare_assignment(Z = sample(rep(0:1, length.out = N))) +
declare_measurement(Y = Y_Z_0 * (1 - Z) + Y_Z_1 * Z)
head(draw_data(design))
Declare the data-generating model
Description
The model describes the world the design runs in. It does not have to be correct: declaring one you doubt is how you find out whether the design still works when you are wrong about it.
Usage
declare_model(..., label = "model", draws = 1L)
Arguments
... |
(optional) Named arguments forwarded to
|
label |
(optional) Step label. Defaults to |
draws |
(optional) Number of nested draws for this step. Defaults to
|
Details
Declares a step that builds (or augments) the population data via
fabricatr::fabricate(). The first model step in a design receives
data = NULL, so it must specify N (and any variables) directly.
Subsequent model steps add columns to the existing data.
Value
A design_step (class c("design_step", "dd", "function")): a
function that takes the current data frame and returns a tibble with the
declared columns added (or built from scratch, for the first step). Add it
to a design with +.
See Also
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_inquiry(),
declare_measurement(),
declare_notes(),
declare_parameters(),
declare_sampling(),
declare_step(),
declare_test()
Examples
design <- declare_model(N = 50, U = rnorm(N), Y = U + 1)
head(draw_data(design))
# A second model step adds columns to the data the first one made.
design <-
declare_model(N = 50, U = rnorm(N)) +
declare_model(Y_Z_0 = U, Y_Z_1 = U + 0.5)
head(draw_data(design))
Declare quantities computed while a design runs
Description
Records a named quantity at a point in the pipeline and makes it available to every step that follows. A note is computed when the design runs, at the position it is declared, from whatever is in scope there: the parameters, the notes already taken, and the data as they stand at that moment.
declare_model(N = 100, Y = rnorm(N)) + declare_notes(tallest = max(Y)) + declare_sampling(S = complete_rs(N, n = 10)) + declare_inquiry(shortfall = mean(tallest - Y))
tallest is the largest value in the population, and the inquiry reads it
after sampling has thrown most of that population away. Notes are what
carry a quantity across a step that destroys the data it was computed from.
Usage
declare_notes(..., label = "notes")
Arguments
... |
(optional) Named quantities. Each is evaluated when the design runs, in order, and may read the parameters, the notes taken before it, and the current data. |
label |
(optional) Step label. Defaults to |
Details
A note is fixed from the moment it is taken until the end of that run. It
is not recomputed by the steps that read it, so tallest above stays the
population maximum rather than becoming the sample maximum. It is redrawn
on the next run, because the data are. Declaring the same name again later
overwrites it from that point on and leaves the earlier steps alone.
A note that reads no data is the ordinary way to write a quantity derived from a parameter:
declare_parameters(m_arms = 3) +
declare_notes(ks = seq_len(m_arms)[-1],
term_names = paste0("factor(Z)", ks))
m_arms is the one thing a caller sets: redesign(design, m_arms = 4).
ks and term_names follow from it, and cannot be set independently
without contradicting it, so redesign() refuses them and
design_parameters() does not list them. That is the difference
between a note and a parameter. A declare_parameters() step names what a
caller may change; a declare_notes() step names what the design works out
for itself.
Within one call, each note may read the ones declared before it. A note may not share a name with a declared parameter.
The step generates no data and adds no rows to a design's output.
Value
A design_step (class c("design_step", "dd", "function"))
whose dots attribute holds the note expressions. Called on a data
frame, it returns the data unchanged. Add it to a design with +.
See Also
declare_parameters() for the quantities a caller may change,
design_notes() for the notes a design takes.
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_inquiry(),
declare_measurement(),
declare_model(),
declare_parameters(),
declare_sampling(),
declare_step(),
declare_test()
Examples
# A quantity that outlives the data it is computed from.
design <-
declare_model(N = 100, Y = rnorm(N)) +
declare_notes(population_mean = mean(Y)) +
declare_sampling(S = complete_rs(N, n = 10)) +
declare_inquiry(gap = mean(Y) - population_mean)
draw_estimands(design)
# A quantity derived from a parameter, so `m_arms` is the only name a
# redesign can set.
design <-
declare_parameters(m_arms = 3) +
declare_notes(inquiry_names = paste0("ate_", seq_len(m_arms)[-1])) +
declare_model(N = 60, u = rnorm(N)) +
declare_inquiry(handler = function(data) {
data.frame(inquiry = inquiry_names, estimand = 0)
})
design_parameters(design)
design_notes(design)
draw_estimands(redesign(design, m_arms = 4))
Declare the parameters of a design
Description
Names the quantities a design is built from, so that redesign() changes
them and nothing else. A parameter declared here is bound for every step
that follows, and takes precedence over a binding of the same name in the
workspace.
Parameters are ordinary R expressions evaluated once, when the design is
built, and each may read the ones declared before it:
declare_parameters(m_arms = 3, ks = seq_len(m_arms)[-1]). They are not
redrawn on each simulation, which is what separates a parameter from a
random variable: declare_parameters(u = rnorm(1)) fixes one number for
the life of the design.
Usage
declare_parameters(..., label = "parameters")
Arguments
... |
(optional) Named parameters. Each is evaluated once, in order, and may read the parameters declared before it. |
label |
(optional) Step label. Defaults to |
Details
Without a declare_parameters() step, a design's parameters are whatever
its expressions read out of the environment they were written in, and
redesign() finds them by name. That works and it stays supported:
declare_model(N = n_units, ...) with n_units defined outside the design
needs no declaration.
What does need a name is a number written into the design. declare_model(N = 500) puts 500 in the design, and nothing outside it names that number, so
redesign(design, N = 1000) errors rather than rewriting the argument
because its name matched. Giving the value a name outside the design fixes
that on its own, and is the usual answer; declaring it here earns its place
when several steps read the value, or when a column shares its name. A
redesign changes the declared parameter, and a column of the same name is
left alone, because it belongs to the data rather than to the design.
The step generates no data and is skipped when the design runs.
Value
A design_step (class c("design_step", "dd", "function"))
that carries the declared parameters and their values. Called on a data
frame, it returns the data unchanged. Add it to a design with +.
See Also
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_inquiry(),
declare_measurement(),
declare_model(),
declare_notes(),
declare_sampling(),
declare_step(),
declare_test()
Examples
design <-
declare_parameters(n_units = 100, effect = 0.5) +
declare_model(N = n_units, U = rnorm(N), Y_Z_0 = U, Y_Z_1 = U + effect) +
declare_inquiry(ATE = mean(Y_Z_1 - Y_Z_0)) +
declare_assignment(Z = sample(rep(0:1, length.out = N))) +
declare_measurement(Y = Y_Z_0 * (1 - Z) + Y_Z_1 * Z)
nrow(draw_data(design))
nrow(draw_data(redesign(design, n_units = 40)))
# A later parameter may read an earlier one.
design <- declare_parameters(m_arms = 3, ks = seq_len(m_arms)[-1]) +
declare_model(N = 60) +
declare_assignment(Z = complete_ra(N, conditions = seq_len(m_arms)))
design_parameters(design)
Deprecated alias for declare_model()
Description
declare_population() is retained for compatibility with older scripts but
will be removed in a future version. Use declare_model() instead.
Usage
declare_population(...)
Arguments
... |
(optional) Forwarded to |
Value
A design_step, as declare_model() returns.
Declare a sampling procedure
Description
Draws the sample from the population, keeping the rows where the sampling
indicator S is 1. Name the indicator S, as in
declare_sampling(S = complete_rs(N, n = 50)), or say which rows to keep
with filter = ; a sampling step that produces neither keeps every row and
warns.
Usage
declare_sampling(..., filter = NULL, label = "sampling", draws = 1L)
Arguments
... |
(optional) Named arguments forwarded to
|
filter |
(optional) Unquoted expression evaluated against the data;
rows where the expression is |
label |
(optional) Step label. Defaults to |
draws |
(optional) Number of nested draws for this step. Defaults to
|
Value
A design_step (class c("design_step", "dd", "function")): a
function that takes the current data frame and returns the rows sampled,
with any declared columns added. Add it to a design with +.
See Also
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_inquiry(),
declare_measurement(),
declare_model(),
declare_notes(),
declare_parameters(),
declare_step(),
declare_test()
Examples
design <-
declare_model(N = 200, Y = rnorm(N)) +
declare_sampling(S = sample(rep(0:1, length.out = N)))
nrow(draw_data(design))
Declare a custom data-handling step
Description
Wraps an arbitrary handler function as a step in the design. The handler
must accept data as its first argument and return a data frame.
Usage
declare_step(handler, ..., label = "custom_step", draws = 1L)
Arguments
handler |
(required) A function whose first argument is |
... |
(optional) Additional arguments passed to |
label |
(optional) Step label. Defaults to |
draws |
(optional) Number of nested draws for this step. Defaults to
|
Value
A design_step (class c("design_step", "dd", "function")): a
function that takes the current data frame and returns what handler
returns for it. Add it to a design with +.
See Also
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_inquiry(),
declare_measurement(),
declare_model(),
declare_notes(),
declare_parameters(),
declare_sampling(),
declare_test()
Examples
step <- declare_step(handler = function(data, k) {
data$X2 <- data$X * k
data
}, k = 2)
df <- data.frame(X = 1:5)
step(df)
# A tidyselect handler receives the column names, not their contents.
wide <- declare_step(
id_cols = pair, names_from = role, values_from = c(ID, a),
handler = tidyr::pivot_wider
)
long <- data.frame(pair = rep(1:3, each = 2), role = rep(c("A", "B"), 3),
ID = sprintf("%03d", 1:6), a = 1:6)
wide(long)
Declare a hypothesis test
Description
Like declare_estimator() but the result table does not gain an inquiry
column; intended for tests not tied to an estimand.
Usage
declare_test(
...,
.method = NULL,
.summary = tidy_try,
term = NULL,
label = "test",
handler = NULL,
draws = 1L
)
Arguments
... |
(optional) Arguments forwarded, as written, to |
.method |
(optional) The model-fitting function. Defaults to
|
.summary |
(optional) Function used to tidy |
term |
(optional) Which model terms to report. A character vector keeps
exactly those terms, in that order, and errors if any is absent from the
tidied output; |
label |
(optional) Step label. Defaults to |
handler |
(optional) A function. When supplied, the test bypasses
|
draws |
(optional) Number of nested draws for this step. Defaults to
|
Value
A design_step, as declare_estimator() returns, whose estimates
carry no inquiry column.
See Also
Other design declarations:
declare_assignment(),
declare_estimator(),
declare_inquiry(),
declare_measurement(),
declare_model(),
declare_notes(),
declare_parameters(),
declare_sampling(),
declare_step()
Examples
design <- declare_model(N = 30, Z = rep(0:1, 15), Y = Z + rnorm(N)) +
declare_test(Y ~ Z, term = "Z", label = "diff")
draw_estimates(design)
Default diagnosands
Description
Returns the standard set of diagnosands. A diagnosand is a summary of a design's behaviour across simulations, so each one is computed over the whole set of draws rather than within any single draw.
Usage
default_diagnosands()
Details
mean_estimandAverage of the estimand across draws. The estimand varies from draw to draw whenever the model is stochastic.
mean_estimateAverage of the estimator's estimate across draws.
biasAverage of estimate minus estimand. Zero means the estimator lands on the estimand on average, not that it is close on any one draw.
sd_estimateStandard deviation of the estimates, which is the true sampling variability of the design.
rmseRoot mean squared error, the average distance between estimate and estimand. It counts bias and variability together, so it is the one to read when an estimator trades one against the other.
powerShare of draws in which the p-value is at or below 0.05. Read it as power only when the effect is real; under a true null the same number is the false positive rate.
coverageShare of draws in which the confidence interval contains the estimand. A 95 percent interval should give 0.95. Materially lower means the intervals are too narrow and the design overstates its own precision.
Value
A diagnosands design_step, as declare_diagnosands() returns,
holding the seven diagnosands listed under Details.
See Also
Other diagnosands:
declare_diagnosands(),
format.diagnosis(),
select_diagnosands(),
set_diagnosands()
Examples
default_diagnosands()
Delete a step from a design (deprecated)
Description
Deprecated in 2.0, and warns once per session. Reconstruct the design with
+ instead.
Usage
delete_step(design, step)
Arguments
design |
(required) A |
step |
(required) A label, integer, or |
Value
A design without that step.
See Also
Other modifying a design:
design_notes(),
design_parameters(),
expand_design(),
insert_step(),
redesign(),
replace_step()
Examples
design <- declare_model(N = 30, Y = rnorm(N)) +
declare_inquiry(mu = mean(Y))
delete_step(design, "mu") |> names()
Report the notes a design takes
Description
Lists the names a declare_notes() step declares and the expression each
is computed from. Unlike design_parameters(), no value is reported: a
note has one only while the design is running, and a note computed from
data has a different one on every draw.
The two functions divide a design's names between them. What
design_parameters() lists can be changed with redesign(); what
design_notes() lists cannot, and follows from what can.
Usage
design_notes(design)
Arguments
design |
(required) A |
Value
A data frame with one row per note and columns name, expr (the
expression, as a character label), and step (the position of the step
that declares it).
See Also
Other modifying a design:
delete_step(),
design_parameters(),
expand_design(),
insert_step(),
redesign(),
replace_step()
Examples
design <- declare_parameters(m_arms = 3) +
declare_notes(ks = seq_len(m_arms)[-1]) +
declare_model(N = 60)
design_notes(design)
Report the parameters a design can be redesigned on
Description
Lists the names redesign() can change: the parameters a
declare_parameters() step declares, and the objects the design's
expressions read out of the environments they were written in.
Symbols that resolve to a package (rnorm, complete_ra) are not
parameters and are left out, and neither are names that resolve to nothing,
because those are columns an earlier step created.
Usage
design_parameters(design)
Arguments
design |
(required) A |
Value
A data frame of class objects with one row per name per step:
name, value (a display snippet of the value), kind (scalar,
vector, list, data, function, or other), declared (whether a
declare_parameters() step declares it), and step (the position of the
step that reads it), plus the list
columns quosure and env that locate the binding. Rows are in step
order. It prints aggregated to one row per name.
See Also
Other modifying a design:
delete_step(),
design_notes(),
expand_design(),
insert_step(),
redesign(),
replace_step()
Examples
design <- declare_parameters(n_units = 100) +
declare_model(N = n_units, Y = rnorm(N))
design_parameters(design)
Diagnose a design
Description
Simulates the design and computes diagnosands (bias, RMSE, power, coverage,
and so on) across simulations. If bootstrap_sims > 0, bootstrap standard
errors for each diagnosand are also reported.
Usage
diagnose_design(
...,
sims = NULL,
bootstrap_sims = 100,
diagnosands = NULL,
progress = FALSE
)
diagnose_designs(
...,
sims = NULL,
bootstrap_sims = 100,
diagnosands = NULL,
progress = FALSE
)
Arguments
... |
(required) One or more |
sims |
(optional) Number of simulations. Defaults to |
bootstrap_sims |
(optional) Number of bootstrap replicates for
diagnosand standard errors. Defaults to |
diagnosands |
(optional) A diagnosands |
progress |
(optional) If |
Value
A diagnosis object: a list whose main elements are
simulations_df (the simulations, as simulate_design() returns them),
diagnosands_df (a tibble with one row per group of design, redesign
parameters, inquiry, estimator, outcome, and term, holding n_sims, a
column per diagnosand, and, when bootstrapped, an se(<diagnosand>) column
for each), diagnosand_names, bootstrap_sims, and bootstrap_replicates.
When the simulation was nested, variance_decomposition holds a tibble
decomposing the variance of each quantity by draw level; otherwise it is
NULL.
See Also
Other simulation and diagnosis:
compare_diagnoses(),
diagnose_simulations(),
get_diagnosands(),
get_simulations(),
simulate_design()
Examples
design <- declare_model(N = 40, U = rnorm(N), Z = rep(0:1, 20), Y = U + Z) +
declare_inquiry(ATE = 1) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
diagnose_design(design, sims = 5, bootstrap_sims = 0)
Diagnose a precomputed simulations table
Description
Diagnose a precomputed simulations table
Usage
diagnose_simulations(simulations_df, diagnosands = NULL, bootstrap_sims = 100)
Arguments
simulations_df |
(required) A tibble produced by |
diagnosands |
(optional) A diagnosands |
bootstrap_sims |
(optional) Number of bootstrap replicates. Defaults
to |
Value
A diagnosis object, as diagnose_design() returns.
See Also
Other simulation and diagnosis:
compare_diagnoses(),
diagnose_design(),
get_diagnosands(),
get_simulations(),
simulate_design()
Examples
design <- declare_model(N = 40, U = rnorm(N), Z = rep(0:1, 20), Y = U + Z) +
declare_inquiry(ATE = 1) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
sims <- simulate_design(design, sims = 5)
diagnose_simulations(sims, bootstrap_sims = 0)
Draw the realized data from a design
Description
Runs the data-generating steps only. The inquiries and estimators are not run, so a design whose estimator fails still draws its data, and drawing data does not pay to fit models it would throw away.
Usage
draw_data(design, ...)
Arguments
design |
(required) A |
... |
(optional) Named parameter values, as in |
Details
Named parameter values in ... are applied first, so
draw_data(design, theta = 0.5) is draw_data(redesign(design, theta = 0.5)): a convenience for trying a value without naming it above the design
or rewriting the declaration. The names reach the design by redesign()'s
rule, so a name the design does not read warns and is ignored, and a
number written inside a step is refused with the two ways to name it.
data, start and end, 1.x's arguments for running part of a design on
supplied data, are refused with get_estimates() and design[start:end]
as the replacements, unless the design reads a parameter by that name.
Value
A tibble: the data as the last data-generating step leaves it.
See Also
Other drawing from a design:
draw_estimands(),
draw_estimates(),
get_estimates(),
run_design()
Examples
design <- declare_model(N = 25, X = rnorm(N))
df <- draw_data(design)
nrow(df)
# A value the declaration leaves free, supplied at draw time
model <- declare_model(N = 25, D = rbinom(N, 1, 0.5), Y = theta * D + rnorm(N))
head(draw_data(model, theta = 0.5))
Draw the realized estimands
Description
Runs the data-generating and inquiry steps only, not the estimators.
Usage
draw_estimands(design, ...)
draw_estimand(design, ...)
Arguments
design |
(required) A |
... |
(optional) Named parameter values, as in |
Value
A tibble with columns inquiry and estimand, one row per
inquiry.
See Also
Other drawing from a design:
draw_data(),
draw_estimates(),
get_estimates(),
run_design()
Examples
design <- declare_model(N = 25, U = rnorm(N), Y = U) +
declare_inquiry(mu = mean(Y))
draw_estimands(design)
Draw the realized estimates
Description
Runs the design once and returns its estimates joined to inquiries.
Usage
draw_estimates(design, ...)
Arguments
design |
(required) A |
... |
(optional) Named parameter values, as in |
Value
The estimates from one run: a tibble with one row per estimate: the
tidied columns (term, estimate, std.error, p.value, conf.low,
conf.high, and so on), estimator, and, where an estimator names an
inquiry, inquiry and the realized estimand. A design with no
estimator returns its estimands instead.
See Also
Other drawing from a design:
draw_data(),
draw_estimands(),
get_estimates(),
run_design()
Examples
design <- declare_model(N = 30, U = rnorm(N), Y = U) +
declare_inquiry(mu = mean(Y)) +
declare_estimator(Y ~ 1, .method = lm, term = "(Intercept)",
inquiry = "mu", label = "ols")
draw_estimates(design)
Build a family of designs from a designer function (deprecated)
Description
Deprecated in 2.0. Call the designer once and redesign() the result:
redesign(designer(), N = c(100, 200)) does what
expand_design(designer, N = c(100, 200)) did, and reaches the same
names, since a designer's argument is a name the design reads.
expand_design() still works and warns once per session.
Usage
expand_design(.designer, ..., .expand = TRUE)
Arguments
.designer |
(required) A function returning a |
... |
(optional) Named parameter values to vary, passed to
|
.expand |
(optional) If |
Details
The one thing it did that redesign() cannot is rebuild a design whose
shape depends on an argument, such as a designer that adds a step when
blocked = TRUE. For that, call the designer with each value.
Value
A design or a named list of designs, as redesign() returns.
See Also
Other modifying a design:
delete_step(),
design_notes(),
design_parameters(),
insert_step(),
redesign(),
replace_step()
Examples
designer <- function(N = 50) {
declare_model(N = N, Y = rnorm(N)) + declare_inquiry(mu = mean(Y))
}
# deprecated
designs <- suppressWarnings(expand_design(designer, N = c(10, 20)))
# instead
designs <- redesign(designer(), N = c(10, 20))
length(designs)
Format a diagnosis for display
Description
Rounds the diagnosands, puts each bootstrap standard error in parentheses on
a second row beneath its estimate, and gives the columns display names
(mean_estimand becomes Mean Estimand). This is what print.diagnosis()
shows and what you want in front of knitr::kable().
Usage
## S3 method for class 'diagnosis'
format(x, digits = 2, ...)
reshape_diagnosis(diagnosis, digits = 2)
Arguments
x |
(required) A |
digits |
(optional) Number of decimal places. Defaults to |
... |
(optional) Ignored. |
diagnosis |
(required) A |
Details
The standard-error rows appear only when the diagnosis was bootstrapped. At
bootstrap_sims = 0 there are no replicates, so the table is one row per
group and there are no parentheses.
It is a format() method because that is what it does. R's format() is
the generic for "the character representation this object prints as", and
print() is documented as calling it. The three views of a diagnosis are
worth keeping straight: get_diagnosands() is wide and numeric with
se(bias) as a sibling column, tidy() is long and numeric with the
standard error and interval as fields of each row, and this is wide and
character with the standard error rendered beneath its estimate. Only the
first two can be computed on. This one is a rendering of the first, a pure
function of it and digits, and it carries strictly less information than
either: the interval is not in it and the precision is gone.
reshape_diagnosis() is DeclareDesign's name for the same thing and calls
this method, so code written against DeclareDesign keeps working.
It returns a data.frame rather than a tibble because every column is a
formatted string, and a tibble would print a <chr> row under a display
table.
Redesign parameter columns keep their own names, since prob_each is the
argument the reader passed and not a phrase to be title-cased.
DeclareDesign's select and exclude arguments are deliberately absent:
the result is a data frame, so select() already chooses columns from it,
and an argument that duplicates a verb is the wart this package exists to
remove.
Value
A data.frame of character columns: the grouping columns and one
column per diagnosand under its display name, with each bootstrap
standard error in parentheses on the row beneath its estimate.
See Also
Other diagnosands:
declare_diagnosands(),
default_diagnosands(),
select_diagnosands(),
set_diagnosands()
Examples
design <- declare_model(N = 30, Y = rnorm(N), Z = rep(0:1, 15)) +
declare_inquiry(ATE = 0) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
d <- diagnose_design(design, sims = 5, bootstrap_sims = 0)
format(d)
# DeclareDesign's name for the same table
reshape_diagnosis(d)
# choose columns with select(), on the data frame it returns
format(d) |> dplyr::select(Term, Bias, Power)
Get the diagnosands table from a diagnosis
Description
Get the diagnosands table from a diagnosis
Usage
get_diagnosands(diagnosis)
Arguments
diagnosis |
(required) A |
Value
The diagnosis's diagnosands_df: a tibble with one row per group
(design, inquiry, estimator, outcome, and term), holding n_sims, a
column per diagnosand, and, when bootstrapped, an se(<diagnosand>)
column for each.
See Also
Other simulation and diagnosis:
compare_diagnoses(),
diagnose_design(),
diagnose_simulations(),
get_simulations(),
simulate_design()
Examples
design <- declare_model(N = 30, Y = rnorm(N), Z = rep(0:1, 15)) +
declare_inquiry(ATE = 0) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
d <- diagnose_design(design, sims = 5, bootstrap_sims = 0)
get_diagnosands(d)
Get estimates for a fixed dataset
Description
Runs only the estimator steps of a design against a supplied data frame.
Usage
get_estimates(
design,
data = draw_data(design),
start = 1L,
end = length(design)
)
Arguments
design |
(required) A |
data |
(optional) A data frame. Defaults to |
start |
(optional) Integer; first step index to consider. Defaults
to |
end |
(optional) Integer; last step index to consider. Defaults to the last step. |
Value
A tibble with one row per estimate from the estimator and test
steps between start and end, as draw_estimates() returns but
without estimands. An empty tibble when that range holds no estimator.
See Also
Other drawing from a design:
draw_data(),
draw_estimands(),
draw_estimates(),
run_design()
Examples
design <- declare_model(N = 30, U = rnorm(N), Z = rep(0:1, 15), Y = U + Z) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", label = "ols")
df <- draw_data(design)
get_estimates(design, df)
Get the simulations table from a diagnosis
Description
Get the simulations table from a diagnosis
Usage
get_simulations(diagnosis)
Arguments
diagnosis |
(required) A |
Value
The diagnosis's simulations_df: a tibble with one row per
estimate per simulation, as simulate_design() returns it.
See Also
Other simulation and diagnosis:
compare_diagnoses(),
diagnose_design(),
diagnose_simulations(),
get_diagnosands(),
simulate_design()
Examples
design <- declare_model(N = 30, Y = rnorm(N), Z = rep(0:1, 15)) +
declare_inquiry(ATE = 0) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
d <- diagnose_design(design, sims = 5, bootstrap_sims = 0)
get_simulations(d)
Insert a step into a design (deprecated)
Description
Deprecated in 2.0, and warns once per session. Reconstruct the design with
+ instead.
Usage
insert_step(design, new_step, before = NULL, after = NULL)
Arguments
design |
(required) A |
new_step |
(required) A |
before, after |
(required) A label, integer, or |
Value
A design with new_step inserted at the anchor.
See Also
Other modifying a design:
delete_step(),
design_notes(),
design_parameters(),
expand_design(),
redesign(),
replace_step()
Examples
design <- declare_model(N = 30, Y = rnorm(N)) +
declare_inquiry(mu = mean(Y))
new_design <- insert_step(design,
declare_measurement(Y2 = Y * 2),
after = "model")
names(new_design)
Wrap a custom function as a labeled estimator
Description
label_estimator() returns a function suitable for use as .method in
declare_estimator() or declare_test(): it fits the model, tidies the
fit, tags the result with estimator and inquiry columns, and keeps the
terms asked for. label_test() is the same function under a second name,
kept so that 1.x scripts run; a test is an estimator whose tidied output
carries a p-value, and nothing in the wrapper depends on which name was
called. 1.x's fn = argument is .method = in both.
Usage
label_estimator(
.method,
label = NULL,
inquiry = NULL,
term = NULL,
.summary = tidy_try
)
label_test(
.method,
label = NULL,
inquiry = NULL,
term = NULL,
.summary = tidy_try
)
Arguments
.method |
(required) A function that fits a model from |
label |
(optional) Estimator label, written to the |
inquiry |
(optional) Inquiry label (or list of labels); the first is
written to the |
term |
(optional) Character vector of terms to keep. |
.summary |
(optional) Function for tidying the model fit. Defaults to
|
Value
A function of data and ... that calls
.method(data = data, ...), tidies the fit with .summary, and returns
the resulting tibble with the estimator and inquiry columns set and
its rows restricted to term.
Examples
my_est <- label_estimator(
function(data, ...) lm(Y ~ Z, data = data),
label = "lm", inquiry = "ATE", term = "Z"
)
df <- data.frame(Y = rnorm(20), Z = rep(0:1, 10))
my_est(df)
Join estimates to their inquiries
Description
Used in run_design() and simulate_design() to attach estimands to
estimator output via the inquiry label.
Usage
merge_estimates_inquiries(estimates, inquiries)
Arguments
estimates |
A tibble of estimator output. |
inquiries |
A tibble of inquiry output. |
Details
The join is on every column the two tables share, so a labelled estimator
matches on inquiry, a conjoint matches on the attribute and level
columns both of its tables carry, and an estimator declared without
inquiry = still matches on sim_ID alone. That last case is what makes
the one-inquiry, one-estimator design work without the label: the
simulation's only inquiry is the one attached.
When the join produces more rows than either table had, the match was genuinely ambiguous and a warning names the columns it went on.
The columns the join went on are recorded on the result as the matched_on
attribute, which simulate_design() carries to the simulations table and
print.diagnosis() reports when the match was anything other than a
labelled one.
Value
A tibble, carrying a matched_on attribute.
Deprecated alias for label_estimator()
Description
model_handler() and tidy_estimator() are retained for compatibility but
will be removed in a future version. Use label_estimator() instead.
Usage
model_handler(...)
tidy_estimator(...)
Arguments
... |
(required) Forwarded to |
Value
A function, as label_estimator() returns.
Population variance
Description
Computes the (uncorrected) variance: the mean squared deviation from the mean. Useful for design-based standard errors. Missing values are dropped.
Usage
pop.var(x)
Arguments
x |
(required) A numeric vector. |
Value
A numeric scalar: the mean of (x - mean(x))^2 over the non-missing
values of x.
Examples
pop.var(c(1, 2, 3, 4, 5))
Print a diagnosand comparison
Description
Print a diagnosand comparison
Usage
## S3 method for class 'compared_diagnoses'
print(x, ...)
Arguments
x |
(required) A |
... |
(optional) Passed to the |
Value
x, invisibly.
Examples
design <- declare_parameters(n_units = 100) +
declare_model(N = n_units, Y = rnorm(N), Z = randomizr::complete_ra(N)) +
declare_inquiry(ATE = 0) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
print(compare_diagnoses(design, redesign(design, n_units = 200),
sims = 20, bootstrap_sims = 20))
Print a design
Description
Lists the steps as the calls that declared them, then the parameters and
objects the design's expressions refer to: the names redesign() can
change, the value each one currently holds, its kind, and which steps
would respond to a change. A design with no such names prints its steps
alone. summary() runs the design once as well and says what each step
did to the data.
Usage
## S3 method for class 'design'
print(x, ...)
Arguments
x |
(required) A |
... |
(optional) Ignored. |
Value
x, invisibly.
Examples
d <- declare_model(N = 30, Y = rnorm(N)) + declare_inquiry(mu = mean(Y))
print(d)
Print a design step
Description
Print a design step
Usage
## S3 method for class 'design_step'
print(x, ...)
Arguments
x |
(required) A |
... |
(optional) Ignored. |
Value
x, invisibly.
Examples
s <- declare_model(N = 10, Y = rnorm(N))
print(s)
Print a diagnosis
Description
Prints the table format.diagnosis() builds: one row of diagnosand
estimates per group, with bootstrap standard errors in parentheses on the
row beneath.
Usage
## S3 method for class 'diagnosis'
print(x, digits = 2, ...)
Arguments
x |
(required) A |
digits |
(optional) Number of decimal places. Defaults to |
... |
(optional) Ignored. |
Value
The data.frame of formatted strings that format.diagnosis()
returns, invisibly.
Examples
design <- declare_model(N = 30, Y = rnorm(N), Z = rep(0:1, 15)) +
declare_inquiry(ATE = 0) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
d <- diagnose_design(design, sims = 5, bootstrap_sims = 0)
print(d)
Print the objects table, one row per name
Description
Prints the table design_parameters() returns, and that print(design)
shows under "Parameters and objects the design refers to", aggregated to
one row per name with five columns. name is the name redesign() can
change. value is a display snippet of what it currently holds. kind is
how redesign() reads a bare replacement: scalar, vector, and list
supply one design per element, while data, function, and other are
single values. declared is TRUE when a declare_parameters() step
declares the name and FALSE when the design reads it from the
environment it was written in. steps lists the positions of the steps
that read the name, which are the steps that would respond to a change.
Usage
## S3 method for class 'objects'
print(x, ...)
Arguments
x |
(required) An |
... |
(optional) Ignored. |
Details
The underlying table has one row per name per step and carries the
quosure and env columns that locate each binding; those are left out of
the print.
Value
x, invisibly.
Examples
tau <- 0.3
design <-
declare_parameters(n_units = 100) +
declare_model(N = n_units, U = rnorm(N), Y_Z_0 = U, Y_Z_1 = U + tau) +
declare_inquiry(ATE = mean(Y_Z_1 - Y_Z_0)) +
declare_assignment(Z = complete_ra(N))
design_parameters(design)
Redesign
Description
Returns a copy of the design with one or more parameters changed, so that
versions can be diagnosed side by side. Several values for a parameter give
several designs: with .expand = TRUE (the default) the cross-product of
the values is taken, and with .expand = FALSE they are zipped
position-wise.
Usage
redesign(.design, ..., .expand = TRUE)
Arguments
.design |
(required) A |
... |
(optional) Named parameter values. A bare atomic vector, and a
bare list, supply one design per element; a data frame, a matrix, a
function, or any classed object is one value. To sweep over such values,
pass a list of them, and to supply one list as a single value wrap it:
|
.expand |
(optional) If |
Details
A parameter that no step responds to draws a warning and is otherwise
ignored. summary() on a design lists the names that are available.
An atomic vector always supplies one value per design, so a parameter that
is itself a vector has to be wrapped: prob_each = list(c(0, 0.5, 0.5)) is
one design, where prob_each = c(0, 0.5, 0.5) is three. Handing a bare
vector to a parameter that currently holds one warns.
A bare list is split the same way, one design per element, so a parameter
whose value is a list is wrapped by the same rule:
levels_list = list(levels) is one design and levels_list = levels is one
design per element of levels. The two are told apart by what the elements
are, since a sweep over lists holds a list in every element, and a bare list
handed to a list-valued parameter whose elements are not lists warns.
Only bare vectors and bare lists are read that way. A data frame, a matrix,
and anything carrying a class are single replacement values, so a design
written as declare_model(data = dataset, ...), with dataset <- pilot
in the workspace, swaps its data with redesign(design, dataset = real)
and needs no wrapping. Naming the parameter dataset rather than after the
data it starts with keeps the name true once it is redesigned. A redesign
reaches the name the design reads the data under, not data, which names
fabricate's argument and belongs to the declaration.
Value
A single design if one combination is supplied, otherwise a list
of designs named by the values that distinguish them: redesign(design, N = c(10, 20)) gives N = 10 and N = 20, so a simulation's design
column, and bind_rows(.id = "design"), carry the values that vary.
Designs are named design_1, design_2, etc. when a parameter's value
cannot be written down, such as a function or a data frame.
See Also
Other modifying a design:
delete_step(),
design_notes(),
design_parameters(),
expand_design(),
insert_step(),
replace_step()
Examples
designer <- function(N) {
declare_model(N = N, Y = rnorm(N)) +
declare_inquiry(mu = mean(Y))
}
design <- designer(50)
redesigned <- redesign(design, N = c(10, 20))
length(redesigned)
# a function-valued parameter
summarizer <- function(x) mean(x)
design <- declare_model(N = 50, Y = rnorm(N)) +
declare_inquiry(mu = summarizer(Y))
redesign(design, summarizer = stats::median)
Objects exported from other packages
Description
These objects are imported from other packages. Follow the links below to see their documentation.
- generics
Replace a step in a design (deprecated)
Description
Deprecated in 2.0, and warns once per session. Reconstruct the design with
+ instead.
Usage
replace_step(design, step, new_step)
Arguments
design |
(required) A |
step |
(required) A label, integer, or |
new_step |
(required) The replacement |
Value
A design with new_step in place of step.
See Also
Other modifying a design:
delete_step(),
design_notes(),
design_parameters(),
expand_design(),
insert_step(),
redesign()
Examples
design <- declare_model(N = 30, Y = rnorm(N)) +
declare_inquiry(mu = mean(Y))
replace_step(design, "mu", declare_inquiry(med = median(Y)))
Execute a design end-to-end
Description
Runs the design once and returns one row per estimate, with the realized
estimands joined on. This is one simulation: simulate_design(sims = 1)
without the sim_ID column.
Usage
run_design(design, ...)
Arguments
design |
(required) A |
... |
(optional) Named parameter values, as in |
Details
Use draw_data() for the realized data frame, draw_estimands() for the
inquiries alone, and draw_estimates() for the estimates alone.
Value
The result of one run: a tibble with one row per estimate: the
tidied columns (term, estimate, std.error, p.value, conf.low,
conf.high, and so on), estimator, and, where an estimator names an
inquiry, inquiry and the realized estimand. A design with no
estimator returns its estimands instead, as draw_estimands() does.
See Also
Other drawing from a design:
draw_data(),
draw_estimands(),
draw_estimates(),
get_estimates()
Examples
design <- declare_model(N = 30, U = rnorm(N), Y = U) +
declare_inquiry(mu = mean(Y))
run_design(design)
Build a diagnosands step from a set of named diagnosands
Description
Two ways to call this, told apart by whether the first argument is a
design_step.
Usage
select_diagnosands(..., alpha = 0.05, subset = NULL, na.rm = FALSE)
Arguments
... |
(required) Diagnosand names to keep, as strings, optionally
preceded by a diagnosands |
alpha |
(optional) Significance level used by |
subset |
(optional) An expression evaluated on the simulations table;
only the rows for which it is |
na.rm |
(optional) Passed to the library diagnosands. Defaults to
|
Details
Given names only, select_diagnosands("bias", "power") builds a fresh
diagnosands step out of the built-in library, which is what DeclareDesign
does. alpha, subset, and na.rm shape the expressions it writes.
Given a diagnosands step first, select_diagnosands(my_diagnosands, "bias")
keeps those entries of that step and nothing else. The expressions are
yours and are copied unchanged, so alpha, subset, and na.rm have
nothing to act on and are refused rather than ignored: set them on the
declare_diagnosands() call that made the set.
A consequence worth knowing: the same name can mean different things in
the two forms. select_diagnosands("bias") writes
mean(estimate - estimand, na.rm = FALSE), following DeclareDesign's
default, while select_diagnosands(default_diagnosands(), "bias") returns
the na.rm = TRUE version default_diagnosands() declares.
The library is a superset of default_diagnosands(): mean_estimand,
mean_estimate, bias, sd_estimate, rmse, power, coverage,
mean_se, type_s_rate, exaggeration_ratio, var_estimate,
mean_var_hat, prop_pos_sig, and mean_ci_length.
Value
A diagnosands design_step, as declare_diagnosands() returns,
holding the named diagnosands in the order given.
See Also
Other diagnosands:
declare_diagnosands(),
default_diagnosands(),
format.diagnosis(),
set_diagnosands()
Examples
select_diagnosands("sd_estimate", "mean_se")
# subset a custom set instead of the library
select_diagnosands(default_diagnosands(), "bias", "rmse")
Attach a citation to a design
Description
Records how the design should be cited, as a utils::bibentry() built from
the fields given, or as the text in citation. cite_design() returns it.
Usage
set_citation(
design,
title = NULL,
author = NULL,
year = NULL,
description = "Unpublished research design declaration",
citation = NULL
)
Arguments
design |
(required) A |
title |
(optional) Title of the design. |
author |
(optional) Author or authors, as a string or a
|
year |
(optional) Year. |
description |
(optional) Note on the entry. Defaults to
|
citation |
(optional) A ready-made citation, as a string or a
|
Value
design, with the citation stored in its citation attribute.
See Also
Other citing a design:
cite_design()
Examples
design <- declare_model(N = 10, Y = rnorm(N))
design <- set_citation(design, title = "Example", author = "Coppock",
year = 2026)
cite_design(design)
Attach diagnosands to a design (deprecated)
Description
Deprecated in 2.0. Stores diagnosands as an attribute on design, which
diagnose_design() uses in place of the defaults when present. Pass the
diagnosands to the diagnosis instead:
diagnose_design(design, diagnosands = ...).
Usage
set_diagnosands(design, diagnosands = default_diagnosands())
Arguments
design |
(required) A |
diagnosands |
(optional) A diagnosands |
Details
Two reasons, beyond diagnosis not being a feature of a design. The
attribute does not survive redesign(), so anything attached this way is
silently gone the first time a parameter moves, and the defaults that
replace it may not be computable from the estimator's output. And a
diagnosands object replaces the default set rather than adding to it, so
declaring one diagnosand drops the other six without saying so.
Value
design, with diagnosands stored in its diagnosands
attribute.
See Also
Other diagnosands:
declare_diagnosands(),
default_diagnosands(),
format.diagnosis(),
select_diagnosands()
Examples
design <-
declare_model(N = 30, Y = rnorm(N)) +
declare_inquiry(mu = mean(Y)) +
declare_estimator(Y ~ 1, .method = lm, term = "(Intercept)", inquiry = "mu")
# instead of set_diagnosands(design, ...)
diagnose_design(
design,
diagnosands = declare_diagnosands(mean_estimate = mean(estimate, na.rm = TRUE)),
sims = 5,
bootstrap_sims = 0
)
Simulate one or more designs
Description
Runs each design sims times, collecting estimands and estimates into a
single long tibble suitable for diagnosis. A design column names the
design each row came from, whether one design is supplied or several.
Usage
simulate_design(..., sims = NULL, progress = FALSE)
simulate_designs(..., sims = NULL, progress = FALSE)
Arguments
... |
(required) One or more |
sims |
(optional) Number of simulations per design. Defaults to |
progress |
(optional) If |
Details
If any step in a design has draws > 1, the simulation runs in nested
mode: each step with draws > 1 fans out, and the total simulation count
equals the product of all draws values across steps. Declared draws
take priority over sims, so supplying both runs the nested simulation and
warns, printing the plan it is running instead.
Steps upstream of the first fan-out run once and are held fixed across the
draws below them, which is what makes declare_assignment(..., draws = 50)
mean fifty randomizations of one population.
Parallelism is handled through the future ecosystem. Call
future::plan(multisession, workers = 4) before simulate_design() and,
if the furrr package is installed, simulations run in parallel with no
other change. Every draw runs on its own L'Ecuyer-CMRG random-number
stream whichever plan is active, so set.seed() before the call gives the
same table sequentially and in parallel. The streams are not those of
DeclareDesign 1.x, so a 1.x seed does not reproduce a 1.x table here.
Value
A tibble with one row per estimate per simulation: design,
sim_ID, the estimate columns (term, estimate, std.error,
p.value, conf.low, conf.high, and so on), estimator, inquiry,
estimand, and a column for each redesign parameter. A nested
simulation adds a <label>_draw column for each step with draws > 1.
See Also
Other simulation and diagnosis:
compare_diagnoses(),
diagnose_design(),
diagnose_simulations(),
get_diagnosands(),
get_simulations()
Examples
design <- declare_model(N = 30, U = rnorm(N), Z = rep(0:1, 15), Y = U + Z) +
declare_inquiry(ATE = 1) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
simulate_design(design, sims = 3)
Summarize a design
Description
Runs the design once and reports what each step did: the rows a data step produced or kept and the columns it added, dropped, or changed; the value each inquiry took; the estimate each estimator returned. The run itself, estimates joined to estimands, comes after the steps, then the parameters and objects the design refers to. Everything the printout shows is on the returned object, so a document or an app can use the pieces.
Usage
## S3 method for class 'design'
summary(object, run = TRUE, ...)
Arguments
object |
(required) A |
run |
(optional) Whether to run the design once. Defaults to |
... |
(optional) Ignored. |
Details
The run is one random draw, so the numbers differ from call to call. A
design whose estimator is slow can be summarized without running it:
run = FALSE gives the steps and the parameters alone, which is what
print() shows.
Value
A summary.design: a list with steps (a tibble with one row per
step: step, label, type, call, and one_run, the account of that
step on this run), parameters and notes (as design_parameters()
and design_notes() return them), ran (logical), and when the design
was run,
data (the final data), inquiries and estimates (as run_design()
returns them).
Examples
n_units <- 30
design <- declare_model(N = n_units, U = rnorm(N), Y = U) +
declare_inquiry(mu = mean(Y)) +
declare_estimator(Y ~ 1, .method = lm, term = "(Intercept)",
inquiry = "mu", label = "ols")
summary(design)
summary(design, run = FALSE)
summary(design)$steps
Summarize a diagnosis
Description
The same report print.diagnosis() gives.
Usage
## S3 method for class 'diagnosis'
summary(object, digits = 2, ...)
Arguments
object |
(required) A |
digits |
(optional) Number of decimal places. Defaults to |
... |
(optional) Ignored. |
Value
The data.frame of formatted strings that format.diagnosis()
returns, invisibly.
Examples
design <- declare_model(N = 30, Y = rnorm(N), Z = rep(0:1, 15)) +
declare_inquiry(ATE = 0) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
summary(diagnose_design(design, sims = 5, bootstrap_sims = 0))
Tidy a diagnosis
Description
Returns the diagnosands in long form, one row per group per diagnosand, with
the bootstrap standard error and percentile confidence interval alongside.
This is the shape to plot from: ggplot(aes(estimate, diagnosand)) + geom_errorbarh(aes(xmin = conf.low, xmax = conf.high)).
Usage
## S3 method for class 'diagnosis'
tidy(x, conf.int = TRUE, conf.level = 0.95, ...)
Arguments
x |
(required) A |
conf.int |
(optional) Whether to include the confidence interval.
Defaults to |
conf.level |
(optional) Confidence level for the interval. Defaults to
|
... |
(optional) Ignored. |
Details
std.error, conf.low, and conf.high come from the bootstrap replicates,
so they appear only when the diagnosis was run with bootstrap_sims > 0.
Value
A tibble with one row per group per diagnosand: the grouping
columns (design, inquiry, estimator, outcome, term, and any
redesign parameters), diagnosand, estimate, and, when bootstrapped,
std.error, conf.low, and conf.high.
Examples
design <- declare_model(N = 30, Y = rnorm(N), Z = rep(0:1, 15)) +
declare_inquiry(ATE = 0) +
declare_estimator(Y ~ Z, .method = lm, term = "Z", inquiry = "ATE",
label = "ols")
d <- diagnose_design(design, sims = 5, bootstrap_sims = 0)
tidy(d)
Tidy a model fit, with a fallback
Description
Tries broom::tidy() with confidence intervals; if that fails (because the
model class has no tidy() method), assembles a minimal tidy table from the
coefficient summary.
Usage
tidy_try(fit, ...)
Arguments
fit |
(required) A fitted model. A data frame is returned as a tibble unchanged. |
... |
(optional) Passed to |
Value
A tibble with one row per term and columns including term,
estimate, std.error, statistic, p.value, conf.low, and
conf.high. When neither broom::tidy() nor coef(summary(fit))
works, a tibble with those columns and no rows.
Examples
fit <- lm(mpg ~ wt, data = mtcars)
tidy_try(fit)
Capture variables as quosures
Description
Convenience alias for rlang::quos() used inside design declarations to
pass through bare expressions.
Usage
vars(...)
Arguments
... |
(optional) Expressions, captured unevaluated. |
Value
A list of quosures of class quosures, one per expression.
Examples
qs <- vars(x, y, z)
length(qs)