Re-executes a design exactly as recorded in its execution receipt,
passing the stored seed, stages, panels, and reps back to
execute(). This avoids reconstructing those arguments by hand from
the receipt fields.
Usage
replay_design(
x,
frame,
fingerprint = c("error", "warn", "inform", "ignore"),
links = NULL,
targets = NULL
)Arguments
- x
A
sampling_designcarrying an execution receipt, as returned byread_design()for a file written from atbl_sample. Atbl_sampleis also accepted and is replayed from its own metadata, which is useful for verifying reproducibility without a file round trip.- frame
The sampling frame the receipt refers to: a data frame for a one-frame call, or the ordered list of stage frames for a call that supplied one register per stage.
- fingerprint
How to respond when
framediffers from the fingerprint stored in the design file:"error"(default),"warn","inform", or"ignore".- links, targets
The link table and the target register, for a shared-weight sample only. Both are required there and refused elsewhere, since accepting them where nothing uses them would return an untransformed sample to someone who believes a transformation was re-applied. Supply the tables the transformation was built from; the result is checked against the integrity the file records.
Details
Given the same frame and compatible recorded implementations, the replayed
sample is identical to the original: the same rows in the same order, the
same weights and design columns, and the same .panel and .replicate
assignments. Only the execution timestamp differs. Replay restores the
execution-time RNG configuration and then restores the caller's RNG state.
It warns when recorded R or package versions differ.
Receipts record a single execute() call. A sample produced by
several calls (a stage continuation or a multi-phase pipeline)
carries a chained flag in its receipt and cannot be replayed.
Save and replay each phase or stage batch separately.
A sample carrying shared weights replays in two steps: the source selection
is re-executed against frame, then the recorded transformation is
re-applied to the links and targets given here. Those two are not in
the file, by design, so they cannot be checked before use; the file instead
records what the source and the result hashed to, and replay is checked
against both. A source that does not reproduce means frame is wrong, and
a result that does not means links or targets is. Both a file and a
live shared sample are accepted.
A frame collection replays component by component and is stacked again
afterwards, so frame is a list named by component. Both a collection read
back from a file and a live frame_stack are accepted. Every component is
checked before any of them runs, since replaying re-executes each
selection. The collection is rebuilt through stack_frames() rather than
by restoring its attributes, so a register that has stopped carrying the
membership column, or whose key is no longer unique, is reported as that.
For a design using a registered custom method, the receipt records a
fingerprint of the implementation (the formals and body of the
registered sample_fn and joint_fn). Replay refuses when the
currently registered function differs from the recorded one, since
identical registry metadata does not imply the same selections.
The fingerprint normalizes formatting and comments and does not
cover the function's enclosing environment: a registered function
that reads from its environment can change behavior without
changing its fingerprint.
A panelized receipt carries a panel assignment record, and it is read
before any panel argument is decoded from it. A record naming an
assignment algorithm or a schema version this samplyr does not know is
samplyr_error_panel_record_unsupported rather than a replay under the
current law. A record that does not carry what the version it states
requires, or that is not a set of named fields at all, is
samplyr_error_panel_record_malformed rather than a repaired one: the
assignment stage decides what the assignment units are, so filling in a
missing one would replay a different assignment of the same sample.
When the design was saved with a frame fingerprint, frame is
compared against it before replaying. A differing frame still yields
a valid sample, but not the recorded one, so the default is to error.
Several frames are compared one by one and reported by position and
recorded label, so a mismatch names the register that moved. After
replaying, the row count is checked against the receipt's
n_selected as a final consistency check.
A sample drawn from one register per stage is replayed by passing
those registers back as a list, in the same order. The receipt
records how many frames the call was given, so supplying the wrong
number is samplyr_error_replay_frame_count rather than a sample
drawn from the wrong pools.
See also
write_design() and read_design() for the receipt
round trip, validate_frame() for checking a frame against a
design before executing.
Other serialization:
as.list.sampling_design(),
design_json(),
write_design()
Examples
sample <- sampling_design() |>
stratify_by(region) |>
draw(n = 100) |>
execute(bfa_eas, seed = 11, panels = 4)
path <- tempfile(fileext = ".json")
write_design(sample, path, frame = bfa_eas)
replayed <- replay_design(read_design(path), bfa_eas)
identical(replayed$ea_id, sample$ea_id)
#> [1] TRUE
identical(replayed$.panel, sample$.panel)
#> [1] TRUE
# One register per stage replays from the same ordered list
regions <- dplyr::distinct(bfa_eas, region)
two_stage <- sampling_design() |>
add_stage(label = "Regions") |>
cluster_by(region) |>
draw(n = 3) |>
add_stage(label = "EAs") |>
draw(n = 5)
registers <- execute(two_stage, regions, bfa_eas, seed = 4)
write_design(registers, path, frame = list(regions, bfa_eas))
identical(
replay_design(read_design(path), list(regions, bfa_eas))$ea_id,
registers$ea_id
)
#> [1] TRUE
unlink(path)