How-to guides
how-to-guides.RmdShort, task-focused guides for common projr workflows. Each section follows the pattern: When to use, Steps, Pitfalls, and See also.
1. Initialise a project
Steps
library(projr)
# Option 1: Interactive prompts (recommended for first-time users)
projr_init_prompt()
# Option 2: Sensible defaults
projr_init()
# Option 3: Full setup with extras
projr_init_full()What gets created:
-
_projr.yml- Project configuration -
DESCRIPTION- Project metadata -
README.md- Project documentation - Directory structure (
_raw_data,_output,_tmp,docs) - Git repository (optional, prompted)
- GitHub repository (optional, prompted)
- License file (optional, prompted)
- Citation file (optional, prompted)
Customising metadata:
# Set license
projr_init_license(license = "MIT")
# Set up citation
projr_init_cite(
title = "My Research Project",
authors = "Jane Doe"
)Pitfalls
-
Git/GitHub prompts: If you haven’t set up GitHub
credentials, the initialisation may fail. See
projr_instr_auth_github()for setup instructions. - Existing files: Initialisation won’t overwrite existing configuration files. Delete or rename them first if you want fresh defaults.
See also
-
?projr_init- Full documentation -
?projr_init_git- Git-specific initialisation -
?projr_init_github- GitHub-specific initialisation
2. Run a development build safely
When to use
When iterating on code and documents, before you’re ready to create a new versioned release.
Steps
# Build all documents, route outputs to cache
projr_build_dev()
# Build specific documents only
projr_build_dev("analysis.Rmd")
projr_build_dev(c("methods.Rmd", "results.Rmd"))Where outputs go:
Development builds route everything to
_tmp/projr/v<version>/:
_tmp/projr/v0.1.0/
├── output/ # Your _output directory content
└── docs/ # Rendered documents
**Clearing _output before dev builds:**
# Clear _output before building (useful for testing)
projr_build_dev(clear_output = "pre")Using paths in your code:
Always use projr_path_get() to ensure paths work
correctly in both dev and final builds:
# In your R Markdown or scripts:
fig_path <- projr_path_get("output", "figures", "plot.png")
png(filename = fig_path)
# ... plotting code ...
dev.off()
# During dev build: saves to _tmp/projr/v0.1.0/output/figures/plot.png
# During final build: saves to _output/figures/plot.pngPitfalls
-
Forgetting
projr_path_get(): If you use hardcoded paths like"_output/plot.png", dev builds will still write to_outputinstead of the cache. -
Cache directory growth: The cache can grow large
over time. Clean it periodically with
unlink("_tmp/projr", recursive = TRUE).
3. Run a final build
Steps
# Patch version bump (0.1.0 -> 0.1.1)
projr_build()
# or explicitly:
projr_build_patch()
# Minor version bump (0.1.0 -> 0.2.0)
projr_build_minor()
# Major version bump (0.1.0 -> 1.0.0)
projr_build_major()What happens:
-
Pre-build: Clears
_output(configurable viaPROJR_OUTPUT_CLEARenv var) - Build: Renders all documents
-
Version bump: Updates project version in
DESCRIPTION - Manifest: Creates manifest linking inputs to outputs
-
Post-build: Copies outputs to
_outputanddocs - Archive: Uploads to configured destinations (GitHub, OSF, local)
- Git commit: Creates commit with version bump (if configured)
Controlling output clearing:
# Set environment variable to control clearing behaviour
# Options: "pre" (before build), "post" (after build), "none"
Sys.setenv(PROJR_OUTPUT_CLEAR = "pre")
projr_build()
# Or set in .Renviron file:
# PROJR_OUTPUT_CLEAR=preCustomising commit messages:
The default commit message is “Build v_projr.yml:
Pitfalls
- Uncommitted changes: If you have uncommitted Git changes, the build may fail. Commit or stash changes first.
- Missing archives: If GitHub/OSF uploads fail, check your credentials and network connection.
-
Version conflicts: Ensure the version in
DESCRIPTIONmatches your expectations before building.
4. Archive artefacts
Steps
Archive structure:
projr supports three archive types:
- GitHub Releases - Version-controlled releases on GitHub
- OSF - Open Science Framework storage
- Local - Local directory (e.g., network drive, cloud sync folder)
Configure in _projr.yml:
build:
# GitHub Releases
github:
raw-data:
content: [raw-data]
description: "Raw data files"
cue: "always" # or "new" (default)
output:
content: [output]
description: "Analysis outputs"
docs:
content: [docs]
description: "Rendered documents"
# OSF
osf:
project: "abc123" # OSF project ID
raw-data:
content: [raw-data]
component: "data" # OSF component name
# Local directory
local:
path: "~/Dropbox/my-project-archive"
raw-data:
content: [raw-data]
path: "data"
output:
content: [output]
path: "outputs"Add destinations programmatically:
# Add GitHub archive
projr_yml_dest_add_github(
label = "raw-data",
content = "raw-data",
description = "Raw data files"
)
# Add OSF archive
projr_yml_dest_add_osf(
label = "raw-data",
content = "raw-data",
project = "abc123",
component = "data"
)
# Add local archive
projr_yml_dest_add_local(
label = "raw-data",
content = "raw-data",
path = "~/archive/data"
)Archive parameters:
-
content: Which directory to archive (raw-data, output, docs, cache) -
cue: When to upload - “always”, “new” (only if content changed), “never” -
strategy: “archive” (versioned) or “latest” (overwrite) -
description: Human-readable description
Inspecting archives:
# View current YAML configuration
projr_yml_get()
# Check if files will be uploaded
# (Run a dev build to see what would happen without actually uploading)
projr_build_dev()Pitfalls
- Large files on GitHub: GitHub has a 2GB limit for release assets. Use OSF or local for larger datasets.
-
OSF authentication: Set up OSF credentials first
with
projr_instr_auth_osf(). - Network failures: Archives may fail silently. Check the build log for errors.
5. Restore artefacts
Steps
Restore entire repository:
# Clone repo and restore raw data
projr_restore_repo("owner/repo")
# Clone to specific directory
projr_restore_repo("owner/repo", path = "~/projects/my-project")
# Restore from current working directory (if already cloned)
projr_restore_repo_wd()Restore specific directories:
# Restore raw data only
projr_restore(label = "raw-data")
# Restore multiple directories
projr_restore(label = c("raw-data", "output"))
# Restore specific version
projr_restore(label = "raw-data", version = "v0.1.0")Restoration sources:
projr checks these sources in order:
- GitHub Releases (if configured in
_projr.yml) - OSF (if configured)
- Local archives (if configured)
Mapping labels to paths:
The _projr.yml file defines where each label’s content
is stored:
6. Define directories and labels
Steps
Default labels:
projr provides these default labels:
-
raw-data→_raw_data -
cache→_tmp -
output→_output -
docs→docs
Add custom labels in _projr.yml:
directories:
raw-data:
path: _raw_data
raw-data-public:
path: _raw_data_public
raw-data-private:
path: _raw_data_private
cache:
path: _tmp
output:
path: _output
output-figures:
path: _output/figures
docs:
path: docsRules for directory labels:
- No nesting: Each label maps to a single path
- Unique labels: Each label must be unique
-
Fixed prefixes: Labels must start with
raw,cache,output, ordocs - Auto-creation: Directories are created automatically on build
Using custom labels:
# Access custom paths
projr_path_get("raw-data-public")
# "_raw_data_public"
projr_path_get("output-figures", "plot.png")
# "_output/figures/plot.png"7. Use profiles
When to use
When you need different configurations for different contexts (e.g., development vs production, different collaborators).
Steps
Create a profile:
# Create a profile based on _projr.yml
projr_profile_create("dev")
# This creates _projr-dev.ymlCustomise the profile:
Edit _projr-dev.yml to override specific settings:
# Only differences from _projr.yml
build:
github:
enabled: false # Disable GitHub uploads in dev profile
directories:
output:
path: _output_dev # Use different output directoryUse a profile:
# Set environment variable
Sys.setenv(PROJR_PROFILE = "dev")
# Or set in .Renviron:
# PROJR_PROFILE=dev
# Now all projr functions use _projr-dev.yml
projr_build()Check active profile:
projr_profile_get()
# "dev"Delete a profile:
projr_profile_delete("dev")8. View and manage build logs
Steps
View build history:
All builds are automatically logged to
cache/projr/log/{dev,output}/history/builds.md:
# View dev build history
file.edit("cache/projr/log/dev/history/builds.md")
# View output build history
file.edit("cache/projr/log/output/history/builds.md")View detailed build logs:
Each build creates a detailed Quarto log file organized by date:
# List recent dev build logs
list.files("cache/projr/log/dev/output",
recursive = TRUE, pattern = "\\.qmd$")
# Render a log file to HTML
quarto::quarto_render("cache/projr/log/dev/output/2025-Nov-11/14-07-00.qmd")Control logging:
# Disable detailed log file creation (history still maintained)
Sys.setenv(PROJR_LOG_DETAILED = "FALSE")
projr_build_dev()
# Re-enable detailed logging
Sys.setenv(PROJR_LOG_DETAILED = "TRUE")Clear old logs:
# Clear all logs
projr_log_clear()
# Clear only dev logs
projr_log_clear(build_type = "dev")
# Keep history, clear detailed logs only
projr_log_clear(history = FALSE, output = TRUE)
# Clear logs before a specific date
projr_log_clear(before_date = "2025-01-01")Pitfalls
-
Log directory location: Logs are in
cache/projr/log, not in_tmp. - Never auto-cleared: Unlike cache, logs are never cleared automatically—manage manually.
- Disk space: Logs accumulate over time; clear old logs periodically.
See also
?projr_log_clear?projr_build- Console output control: Use
output_levelparameter in build functions
9. Query manifest to track file changes
When to use
When you need to: - Understand which files changed between versions - Track when specific outputs were last modified - Verify data provenance and reproducibility - Audit project history
Steps
1. Compare two versions:
# See what files changed between v0.0.1 and v0.0.2
changes <- projr_manifest_changes("0.0.1", "0.0.2")
# View the results
changes
# Returns: label, fn, change_type (added/modified/removed),
# hash_from, hash_to
# Filter by directory
output_changes <- projr_manifest_changes(
"0.0.1", "0.0.2",
label = "output"
)2. Track files across multiple versions:
# See all files and when they last changed from v0.0.1 to current
file_history <- projr_manifest_range("0.0.1")
# View the results
file_history
# Returns: label, fn, version_first, version_last_change, hash
# Limit to specific directory and version range
raw_data_history <- projr_manifest_range(
"0.0.1", "0.0.5",
label = "raw-data"
)3. Check when directories last changed:
# See most recent changes for each directory
last_changes <- projr_manifest_last_change()
# View the results
last_changes
# Returns: label, version_last_change, n_files
# Check status as of a specific version
historical_status <- projr_manifest_last_change("0.0.3")4. Practical examples:
# Did any raw data change since last release?
raw_changes <- projr_manifest_changes(
"0.1.0",
projr_version_get(),
label = "raw-data"
)
if (nrow(raw_changes) > 0) {
message("Raw data has changed - outputs may need regeneration")
}
# Find files that haven't changed in a while
old_files <- projr_manifest_range("0.0.1")
old_files[old_files$version_last_change < "v0.0.5", ]Pitfalls
- Version format: Can use “0.0.1” or “v0.0.1” - both work
- Empty manifests: Returns 0-row data.frame if no changes found
-
Manifest location: Manifest is at project root
(
manifest.csv) -
Only tracks builds: Files are only tracked after
running
projr_build()- Dev builds create temporary manifests but don’t update the main one
11. Configure environment variables
When to use
When you need to: - Control build verbosity and logging behavior - Set up different configurations for development vs. production - Store authentication tokens securely - Override default build behaviors
Quick start
1. Create environment files
file.create("_environment") # Global defaults
file.create("_environment-dev") # Profile-specific
file.create("_environment.local") # Machine-specific (git-ignored)2. Add variables (format:
KEY=value)
# _environment
PROJR_OUTPUT_LEVEL=std
PROJR_LOG_DETAILED=TRUE
# _environment.local (for secrets)
GITHUB_PAT=your_token_here3. Activate environment variables
projr_env_set() # Loads all files in order of precedenceKey environment variables
# Build control
Sys.setenv(PROJR_OUTPUT_LEVEL = "debug") # "none", "std", "debug"
Sys.setenv(PROJR_LOG_DETAILED = "FALSE") # TRUE/FALSE
Sys.setenv(PROJR_CLEAR_OUTPUT = "never") # "pre", "post", "never"
# Profile selection
Sys.setenv(PROJR_PROFILE = "dev")
Sys.setenv(QUARTO_PROFILE = "production")See also
- Environment Variables article - Complete documentation
-
?projr_env_set- Load environment variables -
?projr_profile_get- Get current profile