For the complete documentation index, see llms.txt. This page is also available as Markdown.

Clean Room (R)

Working in Python instead? See Clean Room (Python).

Overview

Clean Room turns an R function into a self-contained, reproducible, interactive application. You wrap a function with reproducible(), and GoFigr draws a clean boundary around it: the function can only access the parameters you declare, the packages you list, and publish(). When the function produces a figure, everything—source, data, parameters, environment—is captured and published automatically.

The workflow:

  1. Explore — work however you normally work in RStudio or R Markdown

  2. Distill — pull the core logic into a function with declared parameters

  3. Run — wrap it in reproducible(); GoFigr captures everything

  4. Share — send a link; stakeholders interact with the figure in the browser

Quick Start

Load the package and configure it:

library(gofigR)
library(ggplot2)

gofigR::enable(workspace_name = "Analytics",
               analysis_name  = "Penguins")

Simplest Example

That's it. When the function runs, GoFigr captures:

  • Source code — the function body, extracted via R's AST

  • Parameters — types, defaults, and widget metadata for every argument

  • Data — data frames passed via static(), serialized as Parquet

  • Environment — package names and versions, R version

  • Output — the figures published by the run

Interactive Mode

Add interactive = TRUE to launch a Shiny gadget with parameter widgets. Adjusting any control re-runs the function and updates the plot. Click Publish to push a revision with the current parameter values.

Interactive mode requires a live, interactive R session. Inside knitr/R Markdown rendering or non-interactive scripts the gadget is skipped automatically and the function runs once with its default parameter values.

Choosing the viewer

By default the gadget opens in the RStudio Viewer pane (when RStudio is available) or in a dialog window. Override with the viewer argument:

Parameter Widgets

Parameters are declared as function defaults using one of the parameter constructors below. Plain defaults (e.g. bins = 20) are accepted and treated as static values, but for interactive mode you'll want explicit widget constructors.

slider()

Numeric slider for int and numeric values.

Pass an integer literal (20L) to get an integer slider; the gadget preserves integer type when feeding the value back into your function.

Categorical dropdown with explicit choices.

checkbox()

Boolean toggle.

text_input()

Free-form text input.

static()

Read-only value — no widget is rendered. Use this for data frames and any other value you want captured but not edited interactively. Plain defaults are wrapped in static() automatically, so data = iris and data = static(iris) are equivalent.

In the Clean Room studio the value is available for inspection, and data frames are serialized alongside the revision as Parquet.

Packages

Declare every package the function needs in the packages argument. The clean execution environment will only have access to functions exported by those packages (plus base R and publish()).

Pinning versions

packages accepts a named list to pin explicit versions in the manifest:

If you pass an unnamed character vector, the currently installed versions are resolved automatically.

Imports / aliases

Use the imports argument to record alias-to-package mappings in the manifest (useful for parity with Python clients and for re-creating the environment elsewhere):

Publishing

Call publish() inside the function body. It is always injected into the clean environment — there is no separate "publisher" argument like in Python. The active session set up by gofigR::enable() determines where the figure goes.

In interactive mode publish() is replaced with a no-op preview while you tweak parameters; clicking Publish in the gadget runs the function one more time with the real publish() and shows a link plus QR code to the new revision.

What gets stored

Each published revision includes:

  • Source code — the function body, extracted from the R AST

  • Manifest — JSON with parameter types, widget metadata, package versions, and R version

  • DataFrame parameters — serialized as Parquet

  • Revision flag — marks the revision as a Clean Room revision

Naming the function

Pass name = "..." to give the clean room function a display name in the webapp. Without it the function is anonymous.

Edge Cases and Caveats

Clean room isolation — The function cannot access variables from your global R environment. Only declared package exports, base R, parameters, and publish() are available. This is by design.

DataFrames are copied — Data frame arguments are round-tripped through Parquet serialization before the function sees them. The function receives a deserialized copy, ensuring the clean room version matches what gets stored.

Other params round-trip through JSON — Atomic parameter values go through jsonlite so the function sees the same values that will be persisted in the manifest.

100 MB limit — Total data frame size (via object.size()) must be under 100 MB. If exceeded, a warning is issued and the function runs normally without clean room metadata.

Unsupported parameter types — Only atomic values (numeric, integer, logical, character), data frames, and nested lists of those types are serializable. Anything else triggers a warning and falls back to direct execution.

nanoparquet required — Clean room support requires the nanoparquet package. Without it a warning is issued and the function runs without clean room metadata.

interactive = TRUE outside an interactive session — Inside knitr or non-interactive R, the gadget is skipped and the function runs once with default parameters.

Source code extraction — The function body is captured from the R AST via body(fn). Functions defined inline as the first argument to reproducible() work out of the box. Programmatically constructed functions also work as long as body(fn) returns a valid expression.

Usage in R Markdown / knitr

reproducible() works inside R Markdown chunks. Interactive mode is automatically downgraded to a single-shot run during knitting:

The chunk renders the figure inline, captures the clean room metadata, and publishes a revision to GoFigr — all from a single function call.

Last updated