R Programming / Evaluation, ownership, and reproducible results / Lesson 17
Reproducible artifacts and portability
Preserve the data schema and execution context needed to interpret a saved result.
On this page
Lesson goals
- Distinguish object serialization from a complete analysis record.
- Define exact and approximate round-trip expectations.
- Record encoding, locale, random state, and numerical dependencies.
An artifact needs a declared purpose
A saved summary, a model for prediction, and a checkpoint for continuing an analysis require different state. List the data schema, units, feature or category order, transformation parameters, configuration, and provenance needed for that purpose. A model object alone may not contain every input assumption or externally defined helper. An artifact that loads successfully can still be interpreted with the wrong class mapping or measurement scale. Treat metadata as part of the computation contract rather than a note added after the result. Keep private data and credentials outside public teaching artifacts.
Serialization preserves an object under format rules
saveRDS and readRDS write and restore one R object, while save and load have different named-workspace behavior. The first fixture uses the underlying serialize and unserialize interfaces in memory with one self-created numeric-and-character object. It checks strict round-trip identity under the stated same-environment expectation. This does not test long-term format compatibility, other platforms, external pointer state, or package-dependent classes. Loading a serialized object is not a substitute for validating its schema and intended source. Use an explicit supported format and reviewed loading policy for an actual shared artifact.
artifact <- list(schema = 1L, ids = c("a", "b"), values = c(2, 4))
raw <- serialize(artifact, connection = NULL, version = 3)
restored <- unserialize(raw)
cat("same=", identical(artifact, restored), "\n", sep = "")
cat("schema=", restored$schema, "; rows=", length(restored$ids), "\n", sep = "")
same=TRUE
schema=1; rows=2
The round trip uses a trusted self-created in-memory object; it neither writes a file nor tests compatibility with another R version.
Numeric agreement depends on the intended tolerance
The second fixture contrasts exact equality with a tolerance-based comparison for a familiar floating-point expression. The tolerance is suitable only for this tiny scale demonstration and is not a universal policy for measurements or algorithms. Counts and identifiers often need exact agreement, while computed physical quantities may permit bounded error in stated units. Structural equality is separate from numeric closeness: a result can contain similar numbers in the wrong feature order. Compare types, names, dimensions, categories, and known associations before considering a numeric tolerance sufficient.
computed <- 0.1 + 0.2
reference <- 0.3
cat("exact=", identical(computed, reference), "\n", sep = "")
cat("within tolerance=", isTRUE(all.equal(computed, reference, tolerance = 1e-12)), "\n", sep = "")
contract <- list(features = c("length", "width"), units = c("cm", "cm"))
cat("feature order=", paste(contract$features, collapse = ","), "\n", sep = "")
exact=FALSE
within tolerance=TRUE
feature order=length,width
Approximate numeric agreement does not authorize reordering feature meanings; tolerance and schema identity are different checks.
The environment influences parsing and computation
Record the actual R version, loaded package versions when relevant, platform, locale, timezone, random-generator configuration, and numerical-library context. sessionInfo provides useful environment details, but does not capture the entire analysis automatically. Locale can affect text handling and display, and timezone rules matter for instants. Parallel or numerical-library differences may change floating-point reduction behavior. Decide whether the requirement is exact repeatability, bounded numerical agreement, or similar conclusions across justified replications. State the supported environment and verify it rather than promising portability from a seed or a single saved file.
Verify the restored behavior at a meaningful boundary
Test a known input through preprocessing and the restored calculation, checking output meaning and relevant decisions. Preserve row ids, category levels, missingness rules, and any training-only transform state. For an analysis report, keep the script and synthetic regression fixture alongside the configuration and selected result. For a reusable package, its own dependency and compatibility policy needs separate review. The course has no installed R runtime and makes no serialization, locale, version-portability, or numerical-library execution claim. Its examples are expected behaviors derived from documented base-R contracts, with all displayed code marked illustrative.
Common errors and fixes
A restored fit predicts using reordered features
- Why it happens
- Schema identity was not checked alongside object loading.
- How to fix it
- Restore and validate the feature order and transformations.
- Prevent it next time
- Keep a known-input behavioral fixture with the artifact.
A seed is treated as a complete reproducibility record
- Why it happens
- Generator configuration, call order, software, and data state were omitted.
- How to fix it
- Record the full relevant context and define the required equivalence.
- Prevent it next time
- Test the intended repeatability boundary explicitly.
Approximate comparison hides a category mismatch
- Why it happens
- Numeric tolerance was used where identity was required.
- How to fix it
- Compare names, levels, ids, and structure exactly before numeric values.
- Prevent it next time
- Separate structural and numerical validation steps.
Check your understanding
1. Why does a successful serialize round trip not prove that a model is portable for ten years?
Show worked solution
The tiny test covers one object under one environment and format choice. Future software, packages, classes, and interpretation contracts may differ. State a supported compatibility boundary, preserve readable metadata and the analysis logic, and test restoration in environments actually claimed to be supported.
2. Should a tolerance of 1e-12 be copied to every numeric output?
Show worked solution
No. Tolerance must reflect units, magnitude, accumulated error, and the decision being supported. An exact identifier mismatch cannot be tolerated numerically. A scientific measurement may have a justified much wider uncertainty, while a threshold-near decision may need a stricter behavioral check.
Key takeaways
- Object files and complete analysis records have different scopes.
- Structural identity and numeric closeness require separate checks.
- Portability is a tested boundary with explicit context.