Course outline

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.

About 4 min readContent reviewed
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.

r Illustrative base-R script; R runtime not available during review
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 = "")
Expected output
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.

r Illustrative base-R script; R runtime not available during review
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 = "")
Expected output
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.

Official references