From d7cca61bc0ba49fe8b3fe316a36dce37a007b9e6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Jul 2026 02:50:33 -0600 Subject: [PATCH 1/9] first draft of template-master.R, started testing --- template-config-renv.R | 226 +++++++++++++++++++++++++++++++++++++++++ template-config.R | 45 +++++--- 2 files changed, 259 insertions(+), 12 deletions(-) create mode 100644 template-config-renv.R diff --git a/template-config-renv.R b/template-config-renv.R new file mode 100644 index 0000000..37fb659 --- /dev/null +++ b/template-config-renv.R @@ -0,0 +1,226 @@ +#Template master.R + +# INSTRUCTIONS: +# +# Step 1: Script Order +# +#At the end of this file, add "source("", echo = TRUE)" for each R script +#provided by the author, in the order specified in the README. If the author provides +#a main or master file, only that file must be added. + +#Step 2: Packages +# +# If the README specifies packages that need to be manually installed, add them +# once the renv is activated + + +# Step 3: Generate log file +# +# The following command works on Linux, MacOS, and on Windows +# from the "Terminal" within Rstudio: +# R CMD BATCH master.R +# For alternative ways to do that, see +# https://github.com/labordynamicsinstitute/replicability-training/wiki/R-Tips + +#*================================================ +#* Let's do everything verbosely + +options(verbose=TRUE) + +#*================================================ +#* Let's capture the current working directory, so we can return to it later +temphome <- getwd() + +#*================================================ +#* This lists the libraries that are to be installed to properly set up renv. Leave +#* devtools and rprojroot here; if the authors want you to install others, wait +#* until you've activated renv + +global.libraries <- c("devtools","rprojroot") +install.packages(global.libraries) + +#*==============================================================================================*/ +#* This is specific to AEA replication environment. May not be needed if no confidential data */ +#* are used in the reproducibility check. */ +#* Replicator should check the JIRA field "Working location of restricted data" for right path */ + +sdrive <- "" + +#*================================================ +#* This lists any paths, relative to the root directory, that are to be created. + +create.paths <- c("logs") +# for instance, the following paths might be necessary +#create.paths <- c("data/raw","data/interwrk","data/generated","results") + +################################################ +# Setup for automatic basepath detection # +################################################ + +# Preferred: +# in bash, go to the root directory and type +# "touch .here". Then the following code will work cleanly. + +# Alternative: +# There is already a "name_of_project.Rproj" file in the root directory. +# No further action needed + +# If for some reason that does not work (and it always should) +# manually override: + +# rootdir <- "path/to/root/directory" +rootdir <- "" + +#################################### +# global libraries used everywhere # +#################################### + +posit.date <- Sys.Date() - 31 +# posit.date <- "2020-01-01" # uncomment and set manually if the above does not work + +# PPM only snapshots on weekdays (not sure why...) +# Only check for weekday if posit.date is a Date object, not a string +if (!is.character(posit.date) && weekdays(posit.date) %in% c("Saturday","Sunday")) { + posit.date <- posit.date - 2 +} + +# Check if running on Linux +if (Sys.info()['sysname'] == "Linux") { + # Try to determine the Linux distribution and version using /etc/os-release + if (file.exists("/etc/os-release")) { + os_release <- system("grep -E '^(ID|VERSION_ID|VERSION_CODENAME|ID_LIKE)=' /etc/os-release", intern = TRUE) + + # Extract distribution ID (like ubuntu, debian, rocky) + distro_id <- gsub("ID=", "", grep("^ID=", os_release, value = TRUE)) + distro_id <- gsub("[\"']", "", distro_id) # Remove quotes if present + + # Extract version ID (like 9.4 for Rocky Linux) + version_id <- gsub("VERSION_ID=", "", grep("^VERSION_ID=", os_release, value = TRUE)) + version_id <- gsub("[\"']", "", version_id) # Remove quotes if present + + # Extract codename (like focal, jammy, bullseye) + codename <- gsub("VERSION_CODENAME=", "", grep("^VERSION_CODENAME=", os_release, value = TRUE)) + + # Extract ID_LIKE (like rhel, centos, fedora) + id_like <- gsub("ID_LIKE=", "", grep("^ID_LIKE=", os_release, value = TRUE)) + id_like <- gsub("[\"']", "", id_like) # Remove quotes if present + + # If we found Ubuntu or Debian + if (length(distro_id) > 0 && grepl("^(ubuntu|debian)$", distro_id)) { + # Set CRAN to binary PPM for Ubuntu/Debian + options(repos = c(CRAN = paste0("https://packagemanager.posit.co/cran/__linux__/", codename, "/", posit.date))) + message(paste0("Using binary PPM for Linux distribution: ", distro_id, " (", codename, ")")) + } else if (length(distro_id) > 0 && distro_id == "rocky" && grepl("^9", version_id)) { + # Set CRAN to binary PPM for Rocky Linux 9 + options(repos = c(CRAN = paste0("https://packagemanager.posit.co/cran/__linux__/rhel9/", posit.date))) + message(paste0("Using binary PPM for Linux distribution: ", distro_id, " (version ", version_id, ")")) + } else if (length(distro_id) > 0 && distro_id == "opensuse-leap" && version_id == "15.6") { + # Set CRAN to binary PPM for opensuse-leap 15.6 + options(repos = c(CRAN = paste0("https://packagemanager.posit.co/cran/__linux__/opensuse156/",posit.date))) + message(paste0("Using binary PPM for Linux distribution: ", distro_id, " (version ", version_id, ")")) + } else { + # Use standard PPM with date-based snapshot for other Linux + options(repos = c(CRAN = paste0("https://packagemanager.posit.co/cran/", posit.date))) + } + } else { + # Use standard PPM with date-based snapshot if os-release not available + options(repos = c(CRAN = paste0("https://packagemanager.posit.co/cran/", posit.date))) + } +} else { + # Use standard PPM with date-based snapshot for non-Linux systems + options(repos = c(CRAN = paste0("https://packagemanager.posit.co/cran/", posit.date))) +} + + + +# print option repos +message(paste0("Setting Posit Package Manager snapshot to ",posit.date)) +message("If this does not work, set the date manually in line 22") +getOption("repos") + +# If any package in an renv lockfile is missing a recorded repository, renv::restore() +# will use the PPM date from options("repos") <- your PPM date, not the author's + + +#################################### +# Set path to root directory # +# # +#################################### +options(renv.consent = TRUE) + +if (!requireNamespace("here", quietly = TRUE)) install.packages("here") +if ( rootdir == "" ) rootdir <- here::here() +setwd(rootdir) + + +# Main directories + +for ( dir in create.paths){ + if (file.exists(file.path(rootdir,dir))){ + } else { + dir.create(file.path(rootdir,dir)) + } +} + + +# Setting project-specific library + +# Package management using author's renv when available + +if (file.exists(file.path(rootdir,"renv.lock"))) { + message("Detected renv.lock. Restoring author's renv environment.") + if (!requireNamespace("renv", quietly=TRUE)) install.packages("renv") + renv::restore(prompt=FALSE) +} else { + message("No renv.lock found. Initializing project-local renv.") + if (!requireNamespace("renv", quietly=TRUE)) install.packages("renv") + if (!file.exists(file.path(rootdir,"renv"))) renv::init(bare=TRUE) + + global.libraries <- unique(c(global.libraries,"here")) + + pkgTest <- function(x){ + if(!requireNamespace(x, quietly=TRUE)) + install.packages(x, dependencies=TRUE) + library(x, character.only=TRUE) + } + + invisible(lapply(global.libraries,pkgTest)) + renv::snapshot(prompt=FALSE) +} + + +# Get information on the system we are running on +Sys.info() +R.version + +# Return to the directory we started in +setwd(temphome) + +# keep these lines in the config file +message("======================================================================================================") +message(paste0(" Current working directory: ",getwd())) +print(sessionInfo()) +message("Current libPaths:") +message(.libPaths()) +message(print(list.files(.libPaths()[1]))) + +message("Done with configuration.") + + +#################################### +# Run author code # +# # +#################################### + +#* Add author's programs in the order listed in the README + +author.programs <- c( + "code/master.R" +) + +for (prog in author.programs) { + message(paste0("---- Sourcing: ", prog, " ----")) + source(file.path(rootdir, prog), echo = TRUE) +} + + diff --git a/template-config.R b/template-config.R index 3975deb..2b0c3f7 100644 --- a/template-config.R +++ b/template-config.R @@ -1,10 +1,17 @@ -#Template config.R +#Template master.R # INSTRUCTIONS: # # Step 1: Add or modify code to install libraries # -# If the author provides a setup or config file that installs packages, use it. +# If the author provides a setup or config file that installs packages, list it +#first in the list of programs at the end of this file. If the README specifies +#packages that need to be manually installed, add them to line NUMBER of this file. + + + + + # Then proceed to Step 2. # If not, then copy this code to "config.R", modify the lines after this comment block, # and add "source("config.R", echo = TRUE)" to the main file. @@ -22,22 +29,19 @@ # https://github.com/labordynamicsinstitute/replicability-training/wiki/R-Tips #*================================================ -#* Let's do everything verbosely. +#* Let's do everything verbosely options(verbose=TRUE) - #*================================================ -#* lets capture the current wd, so we can return to it later +#* Let's capture the current working directory, so we can return to it later temphome <- getwd() #*================================================ -#* This lists the libraries that are to be installed. -#* Adjust this by adding on additional ones identified by the authors as necessary +#* This lists the libraries that are to be installed. Leave devtools and rprojroot +#* here; add any additional ones identified by the authors as necessary global.libraries <- c("devtools","rprojroot") -# For example, you can add on two additional ones: -# global.libraries <- c("foreign","devtools","rprojroot","ggplot2","nonsenseR") #*==============================================================================================*/ #* This is specific to AEA replication environment. May not be needed if no confidential data */ @@ -188,11 +192,9 @@ pkgTest <- function(x) ## Add any libraries to this line, and uncomment it. - results <- sapply(as.list(global.libraries), pkgTest) -# lets get back to where we started - +# Return to the directory we started in setwd(temphome) # keep these lines in the config file @@ -206,3 +208,22 @@ message(print(list.files(.libPaths()[1]))) message("Done with configuration.") +#################################### +# Run author code # +# # +#################################### + +#* Add author's programs in the order listed in the README + +author.programs <- c( + "master.R", + # "code/01_clean_data.R", + # "code/02_analysis.R" +) + +for (prog in author.programs) { + message(paste0("---- Sourcing: ", prog, " ----")) + source(file.path(rootdir, prog), echo = TRUE) +} + + From b03b3a4570c0b3a61e21eecff6251af0fc3b81cb Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Jul 2026 01:36:34 -0600 Subject: [PATCH 2/9] fixed some bugs, turned off package installation prompts, added final screensho call --- template-config-renv.R | 49 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/template-config-renv.R b/template-config-renv.R index 37fb659..4876d96 100644 --- a/template-config-renv.R +++ b/template-config-renv.R @@ -11,8 +11,8 @@ #Step 2: Packages # # If the README specifies packages that need to be manually installed, add them -# once the renv is activated - +# to readme.libraries, NOT global.libraries to make sure they're part of the renv +# snapshot. # Step 3: Generate log file # @@ -22,6 +22,12 @@ # For alternative ways to do that, see # https://github.com/labordynamicsinstitute/replicability-training/wiki/R-Tips +# Step 4: Make sure this script carries over +# +# Check any author scripts you're running for lines like rm(list = ls(all = TRUE)) +# These will clear your environment and rootdir will no longer work. Comment these +# lines out + #*================================================ #* Let's do everything verbosely @@ -36,8 +42,17 @@ temphome <- getwd() #* devtools and rprojroot here; if the authors want you to install others, wait #* until you've activated renv -global.libraries <- c("devtools","rprojroot") -install.packages(global.libraries) +# do we actually need devtools and rprojroot? testing but currently no +global.libraries <- c() + +#global.libraries <- c("devtools","rprojroot") +#install.packages(global.libraries) + +#*================================================ +#* If you're running this script in terminal, you may get a mirror error. This +#* line tells R where to install packages from to avoid this error + +options(repos = c(CRAN = "https://cloud.r-project.org")) #*==============================================================================================*/ #* This is specific to AEA replication environment. May not be needed if no confidential data */ @@ -165,6 +180,14 @@ for ( dir in create.paths){ # Setting project-specific library + +# In order to make config.R run smoothly, turn off prompts asking if we want to +# install packages + +options(renv.config.autoloader.enabled = TRUE) +options(renv.config.install.prompt = FALSE) + + # Package management using author's renv when available if (file.exists(file.path(rootdir,"renv.lock"))) { @@ -175,9 +198,17 @@ if (file.exists(file.path(rootdir,"renv.lock"))) { message("No renv.lock found. Initializing project-local renv.") if (!requireNamespace("renv", quietly=TRUE)) install.packages("renv") if (!file.exists(file.path(rootdir,"renv"))) renv::init(bare=TRUE) - + source(file.path(rootdir, "renv", "activate.R")) global.libraries <- unique(c(global.libraries,"here")) +#* If the README specifies additional packages that need to be installed, +#* add them here. This runs AFTER renv has been activated, so they will be +#* installed into the project-local renv library (not your base R library), +#* and will be picked up correctly by renv::snapshot() below. + readme.libraries <- c() # e.g. c("packagename1", "packagename2") + global.libraries <- c(global.libraries, readme.libraries) + + pkgTest <- function(x){ if(!requireNamespace(x, quietly=TRUE)) install.packages(x, dependencies=TRUE) @@ -185,6 +216,12 @@ if (file.exists(file.path(rootdir,"renv.lock"))) { } invisible(lapply(global.libraries,pkgTest)) + + #Install any remaining dependencies renv::dependencies() finds in scripts across + # the project. + missing <- setdiff(renv::dependencies(rootdir)$Package, rownames(installed.packages())) + if (length(missing) > 0) renv::install(missing, prompt=FALSE) + renv::snapshot(prompt=FALSE) } @@ -223,4 +260,6 @@ for (prog in author.programs) { source(file.path(rootdir, prog), echo = TRUE) } +#Final snapshot preserves the packages from a successful run +renv::snapshot(prompt=FALSE) From ee19e1b00ccc4db120b2ba21b355c9a41d7bd4e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Jul 2026 03:08:49 -0600 Subject: [PATCH 3/9] fixed too many packages being installed, moved up Bash instructions --- template-config-renv.R | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/template-config-renv.R b/template-config-renv.R index 4876d96..cf65aeb 100644 --- a/template-config-renv.R +++ b/template-config-renv.R @@ -1,7 +1,19 @@ #Template master.R # INSTRUCTIONS: +# +# Step 0: Bash setup # +# In File Explorer, look for "name_of_project.Rproj" file in the root directory. +# If one exists, go to Step 1. If not, open Git Bash. +# In bash, set your working directory to the root directory (probably 123456/code +#or similar) and type +# "touch .here" + +# If for some reason that does not work (and it always should) +# manually override in line XXX of this file. + + # Step 1: Script Order # #At the end of this file, add "source("", echo = TRUE)" for each R script @@ -197,9 +209,8 @@ if (file.exists(file.path(rootdir,"renv.lock"))) { } else { message("No renv.lock found. Initializing project-local renv.") if (!requireNamespace("renv", quietly=TRUE)) install.packages("renv") - if (!file.exists(file.path(rootdir,"renv"))) renv::init(bare=TRUE) + if (!file.exists(file.path(rootdir,"renv"))) renv::init(bare=TRUE, restart = FALSE) source(file.path(rootdir, "renv", "activate.R")) - global.libraries <- unique(c(global.libraries,"here")) #* If the README specifies additional packages that need to be installed, #* add them here. This runs AFTER renv has been activated, so they will be @@ -208,10 +219,10 @@ if (file.exists(file.path(rootdir,"renv.lock"))) { readme.libraries <- c() # e.g. c("packagename1", "packagename2") global.libraries <- c(global.libraries, readme.libraries) - +# dependencies = NA to prevent _all_ suggested packages from being downloaded pkgTest <- function(x){ if(!requireNamespace(x, quietly=TRUE)) - install.packages(x, dependencies=TRUE) + install.packages(x, dependencies=NA) library(x, character.only=TRUE) } From 6e079c6b74e562a0ddcaa70fde2b4b99a0f3f210 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 18 Jul 2026 02:57:30 -0600 Subject: [PATCH 4/9] added renv.lock search in both directions, fixed snapshot overwriting, updated rootdir as necessary --- ...onfig-renv.R => NEW-template-config-renv.R | 166 +++++++++++------- 1 file changed, 100 insertions(+), 66 deletions(-) rename template-config-renv.R => NEW-template-config-renv.R (62%) diff --git a/template-config-renv.R b/NEW-template-config-renv.R similarity index 62% rename from template-config-renv.R rename to NEW-template-config-renv.R index cf65aeb..f9aef38 100644 --- a/template-config-renv.R +++ b/NEW-template-config-renv.R @@ -4,9 +4,7 @@ # # Step 0: Bash setup # -# In File Explorer, look for "name_of_project.Rproj" file in the root directory. -# If one exists, go to Step 1. If not, open Git Bash. -# In bash, set your working directory to the root directory (probably 123456/code +#In bash, set your working directory to the root directory (probably 123456/code #or similar) and type # "touch .here" @@ -16,15 +14,14 @@ # Step 1: Script Order # -#At the end of this file, add "source("", echo = TRUE)" for each R script -#provided by the author, in the order specified in the README. If the author provides -#a main or master file, only that file must be added. +#At the end of this file, add R scripts to author.programs in the order specified +#in the README. If the author provides a main or master file, likely only that +#file must be added. #Step 2: Packages # # If the README specifies packages that need to be manually installed, add them -# to readme.libraries, NOT global.libraries to make sure they're part of the renv -# snapshot. +# to readme.libraries further down. # Step 3: Generate log file # @@ -49,17 +46,6 @@ options(verbose=TRUE) #* Let's capture the current working directory, so we can return to it later temphome <- getwd() -#*================================================ -#* This lists the libraries that are to be installed to properly set up renv. Leave -#* devtools and rprojroot here; if the authors want you to install others, wait -#* until you've activated renv - -# do we actually need devtools and rprojroot? testing but currently no -global.libraries <- c() - -#global.libraries <- c("devtools","rprojroot") -#install.packages(global.libraries) - #*================================================ #* If you're running this script in terminal, you may get a mirror error. This #* line tells R where to install packages from to avoid this error @@ -84,14 +70,6 @@ create.paths <- c("logs") # Setup for automatic basepath detection # ################################################ -# Preferred: -# in bash, go to the root directory and type -# "touch .here". Then the following code will work cleanly. - -# Alternative: -# There is already a "name_of_project.Rproj" file in the root directory. -# No further action needed - # If for some reason that does not work (and it always should) # manually override: @@ -158,15 +136,14 @@ if (Sys.info()['sysname'] == "Linux") { options(repos = c(CRAN = paste0("https://packagemanager.posit.co/cran/", posit.date))) } - - # print option repos message(paste0("Setting Posit Package Manager snapshot to ",posit.date)) message("If this does not work, set the date manually in line 22") getOption("repos") -# If any package in an renv lockfile is missing a recorded repository, renv::restore() -# will use the PPM date from options("repos") <- your PPM date, not the author's +# Note: if any package in an renv lockfile is missing a recorded repository, renv::restore() +# will use the PPM date from options("repos"), meaning it will use _your_ PPM date, +# not the author's #################################### @@ -189,53 +166,103 @@ for ( dir in create.paths){ } } - -# Setting project-specific library - - # In order to make config.R run smoothly, turn off prompts asking if we want to # install packages options(renv.config.autoloader.enabled = TRUE) options(renv.config.install.prompt = FALSE) +# Bulky renv.lock checks -# Package management using author's renv when available +# How many directory levels to search for an author-provided renv.lock, +# relative to rootdir. Increase either if the author's renv.lock is more than 1 +# directory level up or down from rootdir +lockfile.search.up <- 1 +lockfile.search.down <- 1 -if (file.exists(file.path(rootdir,"renv.lock"))) { - message("Detected renv.lock. Restoring author's renv environment.") - if (!requireNamespace("renv", quietly=TRUE)) install.packages("renv") - renv::restore(prompt=FALSE) -} else { - message("No renv.lock found. Initializing project-local renv.") - if (!requireNamespace("renv", quietly=TRUE)) install.packages("renv") - if (!file.exists(file.path(rootdir,"renv"))) renv::init(bare=TRUE, restart = FALSE) - source(file.path(rootdir, "renv", "activate.R")) - -#* If the README specifies additional packages that need to be installed, -#* add them here. This runs AFTER renv has been activated, so they will be -#* installed into the project-local renv library (not your base R library), -#* and will be picked up correctly by renv::snapshot() below. - readme.libraries <- c() # e.g. c("packagename1", "packagename2") - global.libraries <- c(global.libraries, readme.libraries) +find_author_lockfile <- function(rootdir, up = 1, down = 1) { -# dependencies = NA to prevent _all_ suggested packages from being downloaded - pkgTest <- function(x){ - if(!requireNamespace(x, quietly=TRUE)) - install.packages(x, dependencies=NA) - library(x, character.only=TRUE) + candidates <- data.frame(path = character(0), distance = integer(0)) + + # rootdir itself + self_check <- file.path(rootdir, "renv.lock") + if (file.exists(self_check)) { + candidates <- rbind(candidates, data.frame(path = self_check, distance = 0)) } - - invisible(lapply(global.libraries,pkgTest)) - #Install any remaining dependencies renv::dependencies() finds in scripts across - # the project. - missing <- setdiff(renv::dependencies(rootdir)$Package, rownames(installed.packages())) - if (length(missing) > 0) renv::install(missing, prompt=FALSE) + # check upwards from rootdir + current <- rootdir + for (i in seq_len(up)) { + parent <- dirname(current) + if (parent == current) break # hit filesystem root + candidate <- file.path(parent, "renv.lock") + if (file.exists(candidate)) { + candidates <- rbind(candidates, data.frame(path = candidate, distance = i)) + } + current <- parent + } - renv::snapshot(prompt=FALSE) + # check downwards from rootdir + if (down > 0) { + subdirs <- list.dirs(rootdir, recursive = TRUE, full.names = TRUE) + for (d in subdirs) { + depth <- length(strsplit(sub(paste0("^", rootdir), "", d), .Platform$file.sep)[[1]]) - 1 + if (depth >= 1 && depth <= down) { + candidate <- file.path(d, "renv.lock") + if (file.exists(candidate)) { + candidates <- rbind(candidates, data.frame(path = candidate, distance = depth)) + } + } + } + } + + if (nrow(candidates) == 0) return(NULL) + candidates <- candidates[order(candidates$distance), ] + candidates$path[1] +} + +lockfile_path <- find_author_lockfile(rootdir, up = lockfile.search.up, down = lockfile.search.down) + +#if the author's renv.lock file was found, load their setup and switch rootdir to +#what their code will likely expect +if (!is.null(lockfile_path)) { + author_root <- dirname(lockfile_path) + message("Detected renv.lock at: ", lockfile_path) + rootdir <- author_root + setwd(rootdir) + if (!requireNamespace("renv", quietly = TRUE)) install.packages("renv") + renv::restore(project = author_root, prompt = FALSE) + renv::load(project = author_root) #uses load not activate to prevent a popup asking to switch projects, which breaks the code + +#if no author renv.lock file was found, create a new blank renv project +} else { + message("No renv.lock found within ", lockfile.search.up, " level(s) up / ", + lockfile.search.down, " level(s) down. Initializing project-local renv.") + if (!requireNamespace("renv", quietly = TRUE)) install.packages("renv") + if (!file.exists(file.path(rootdir, "renv"))) renv::init(project = rootdir, bare = TRUE, restart = FALSE) + renv::load(project = rootdir) #uses load not activate to prevent a popup asking to switch projects, which breaks the code } +#If you've run the setup and then the author's code breaks because they didn't +#install some packages, or if the README specifies additional packages that need +#to be installed, add them here to install them into the project's renv library +#(not base R library) and will be picked up correctly by renv::snapshot() below. + +readme.libraries <- c("paletteer", "viridis") #these are color packages for testing, delete + +# Install packages from readme.libraries + + pkgTest <- function(x) + { + if (!require(x,character.only = TRUE)) + { + renv::install(x,prompt = FALSE) + if(!require(x,character.only = TRUE)) stop("Package not found") + } + return("OK") + } + +invisible(lapply(readme.libraries,pkgTest)) # Get information on the system we are running on Sys.info() @@ -271,6 +298,13 @@ for (prog in author.programs) { source(file.path(rootdir, prog), echo = TRUE) } -#Final snapshot preserves the packages from a successful run -renv::snapshot(prompt=FALSE) +#Final snapshot preserves the packages from a successful run but won't overwrite +#the author's original. Not forced, may change later. Select option 1 so you don't +#include `here` in the snapshot, but make sure no other packages are listed. +renv::snapshot( + project = rootdir, + lockfile = file.path(rootdir, "renv.lock.replicator_snapshot"), + packages = c(renv::dependencies(rootdir)$Package, readme.libraries), + prompt = FALSE +) From 112b433e2103e485d0b6bf5a3fa48dd88e59eb09 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Jul 2026 02:14:42 -0600 Subject: [PATCH 5/9] added note about logs; successfully tested in 3 repos on personal laptop --- NEW-template-config-renv.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NEW-template-config-renv.R b/NEW-template-config-renv.R index f9aef38..cb8fe14 100644 --- a/NEW-template-config-renv.R +++ b/NEW-template-config-renv.R @@ -25,7 +25,8 @@ # Step 3: Generate log file # -# The following command works on Linux, MacOS, and on Windows +# Once the code runs successfully, run this to get a log file: +#The following command works on Linux, MacOS, and on Windows # from the "Terminal" within Rstudio: # R CMD BATCH master.R # For alternative ways to do that, see From aa9f96044c6cc0930648180e9193a68e2cc48c98 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Jul 2026 02:05:44 -0600 Subject: [PATCH 6/9] tested successfully on CCSS Cloud --- NEW-template-config-renv.R => template-Main.R | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) rename NEW-template-config-renv.R => template-Main.R (80%) diff --git a/NEW-template-config-renv.R b/template-Main.R similarity index 80% rename from NEW-template-config-renv.R rename to template-Main.R index cb8fe14..124bb2e 100644 --- a/NEW-template-config-renv.R +++ b/template-Main.R @@ -4,34 +4,37 @@ # # Step 0: Bash setup # -#In bash, set your working directory to the root directory (probably 123456/code -#or similar) and type +# In bash, set your working directory to where you're running this (probably 123456/code +# or similar) and type # "touch .here" # If for some reason that does not work (and it always should) -# manually override in line XXX of this file. +# manually override in line 79 of this file. # Step 1: Script Order # -#At the end of this file, add R scripts to author.programs in the order specified -#in the README. If the author provides a main or master file, likely only that -#file must be added. +# At the end of this file, add R scripts to author.programs in the order specified +# in the README. If the author provides a main or master file, likely only that +# file must be added. -#Step 2: Packages + +# Step 2: Packages # # If the README specifies packages that need to be manually installed, add them -# to readme.libraries further down. +# to readme.libraries on line 251. + # Step 3: Generate log file # -# Once the code runs successfully, run this to get a log file: -#The following command works on Linux, MacOS, and on Windows +# Once the code runs successfully, or if you need a log, run this to get a log file: +# The following command works on Linux, MacOS, and on Windows # from the "Terminal" within Rstudio: # R CMD BATCH master.R # For alternative ways to do that, see # https://github.com/labordynamicsinstitute/replicability-training/wiki/R-Tips + # Step 4: Make sure this script carries over # # Check any author scripts you're running for lines like rm(list = ls(all = TRUE)) @@ -48,32 +51,30 @@ options(verbose=TRUE) temphome <- getwd() #*================================================ -#* If you're running this script in terminal, you may get a mirror error. This -#* line tells R where to install packages from to avoid this error +#* If you're running this script in terminal, you may get an error about trying +#* to use CRAN without setting a mirror. This line tells R where to install +#* packages from to avoid this error options(repos = c(CRAN = "https://cloud.r-project.org")) #*==============================================================================================*/ -#* This is specific to AEA replication environment. May not be needed if no confidential data */ -#* are used in the reproducibility check. */ -#* Replicator should check the JIRA field "Working location of restricted data" for right path */ +#* This is specific to AEA replication environment. May not be needed if no +#* confidential data are used in the reproducibility check. Replicator should +#* check the JIRA field "Working location of restricted data" for right path */ sdrive <- "" #*================================================ -#* This lists any paths, relative to the root directory, that are to be created. +#* This lists any paths, relative to the root directory, that are to be created create.paths <- c("logs") -# for instance, the following paths might be necessary -#create.paths <- c("data/raw","data/interwrk","data/generated","results") +# For instance, the following paths might be necessary +# create.paths <- c("data/raw","data/interwrk","data/generated","results") ################################################ # Setup for automatic basepath detection # ################################################ -# If for some reason that does not work (and it always should) -# manually override: - # rootdir <- "path/to/root/directory" rootdir <- "" @@ -142,22 +143,21 @@ message(paste0("Setting Posit Package Manager snapshot to ",posit.date)) message("If this does not work, set the date manually in line 22") getOption("repos") -# Note: if any package in an renv lockfile is missing a recorded repository, renv::restore() -# will use the PPM date from options("repos"), meaning it will use _your_ PPM date, -# not the author's - +# Note: if any package in an renv lockfile is missing a recorded repository, +# renv::restore() will use the PPM date from options("repos"), meaning it will +# use *your* PPM date, not the author's #################################### # Set path to root directory # # # #################################### + options(renv.consent = TRUE) if (!requireNamespace("here", quietly = TRUE)) install.packages("here") if ( rootdir == "" ) rootdir <- here::here() setwd(rootdir) - # Main directories for ( dir in create.paths){ @@ -173,11 +173,12 @@ for ( dir in create.paths){ options(renv.config.autoloader.enabled = TRUE) options(renv.config.install.prompt = FALSE) -# Bulky renv.lock checks +# renv.lock checks # How many directory levels to search for an author-provided renv.lock, -# relative to rootdir. Increase either if the author's renv.lock is more than 1 -# directory level up or down from rootdir +# relative to rootdir. Increase if you can see the author's renv.lock is more than +# 1 directory level up or down from rootdir + lockfile.search.up <- 1 lockfile.search.down <- 1 @@ -185,7 +186,7 @@ find_author_lockfile <- function(rootdir, up = 1, down = 1) { candidates <- data.frame(path = character(0), distance = integer(0)) - # rootdir itself + # check rootdir itself self_check <- file.path(rootdir, "renv.lock") if (file.exists(self_check)) { candidates <- rbind(candidates, data.frame(path = self_check, distance = 0)) @@ -224,8 +225,8 @@ find_author_lockfile <- function(rootdir, up = 1, down = 1) { lockfile_path <- find_author_lockfile(rootdir, up = lockfile.search.up, down = lockfile.search.down) -#if the author's renv.lock file was found, load their setup and switch rootdir to -#what their code will likely expect +# If the author's renv.lock file was found, load their setup and switch rootdir +# to what their code will likely expect if (!is.null(lockfile_path)) { author_root <- dirname(lockfile_path) message("Detected renv.lock at: ", lockfile_path) @@ -235,7 +236,7 @@ if (!is.null(lockfile_path)) { renv::restore(project = author_root, prompt = FALSE) renv::load(project = author_root) #uses load not activate to prevent a popup asking to switch projects, which breaks the code -#if no author renv.lock file was found, create a new blank renv project +# If no author renv.lock file was found, create a new blank renv project } else { message("No renv.lock found within ", lockfile.search.up, " level(s) up / ", lockfile.search.down, " level(s) down. Initializing project-local renv.") @@ -244,12 +245,10 @@ if (!is.null(lockfile_path)) { renv::load(project = rootdir) #uses load not activate to prevent a popup asking to switch projects, which breaks the code } -#If you've run the setup and then the author's code breaks because they didn't -#install some packages, or if the README specifies additional packages that need -#to be installed, add them here to install them into the project's renv library -#(not base R library) and will be picked up correctly by renv::snapshot() below. +# If missing packages, add them here to install into the project's renv library +#(not base R library) so they will be picked up correctly by renv::snapshot() below -readme.libraries <- c("paletteer", "viridis") #these are color packages for testing, delete +readme.libraries <- c() #ex: c("paletteer", "viridis") # Install packages from readme.libraries @@ -272,7 +271,7 @@ R.version # Return to the directory we started in setwd(temphome) -# keep these lines in the config file +# Keep these lines in the config file message("======================================================================================================") message(paste0(" Current working directory: ",getwd())) print(sessionInfo()) @@ -299,9 +298,10 @@ for (prog in author.programs) { source(file.path(rootdir, prog), echo = TRUE) } -#Final snapshot preserves the packages from a successful run but won't overwrite -#the author's original. Not forced, may change later. Select option 1 so you don't -#include `here` in the snapshot, but make sure no other packages are listed. +# Final snapshot preserves the packages from a successful run but won't overwrite +# the author's original. Not forced, may change later. Select option 1 so you don't +# include `here` in the snapshot, but make sure no other packages are listed in +# the warning renv::snapshot( project = rootdir, lockfile = file.path(rootdir, "renv.lock.replicator_snapshot"), From 759ccf2e4aaa224f63ea2163327bf6aae91727e3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 21 Jul 2026 22:37:01 -0600 Subject: [PATCH 7/9] revert changes to template-config.R, all new work is separate in template-Main.R --- template-config.R | 45 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/template-config.R b/template-config.R index 2b0c3f7..3975deb 100644 --- a/template-config.R +++ b/template-config.R @@ -1,17 +1,10 @@ -#Template master.R +#Template config.R # INSTRUCTIONS: # # Step 1: Add or modify code to install libraries # -# If the author provides a setup or config file that installs packages, list it -#first in the list of programs at the end of this file. If the README specifies -#packages that need to be manually installed, add them to line NUMBER of this file. - - - - - +# If the author provides a setup or config file that installs packages, use it. # Then proceed to Step 2. # If not, then copy this code to "config.R", modify the lines after this comment block, # and add "source("config.R", echo = TRUE)" to the main file. @@ -29,19 +22,22 @@ # https://github.com/labordynamicsinstitute/replicability-training/wiki/R-Tips #*================================================ -#* Let's do everything verbosely +#* Let's do everything verbosely. options(verbose=TRUE) + #*================================================ -#* Let's capture the current working directory, so we can return to it later +#* lets capture the current wd, so we can return to it later temphome <- getwd() #*================================================ -#* This lists the libraries that are to be installed. Leave devtools and rprojroot -#* here; add any additional ones identified by the authors as necessary +#* This lists the libraries that are to be installed. +#* Adjust this by adding on additional ones identified by the authors as necessary global.libraries <- c("devtools","rprojroot") +# For example, you can add on two additional ones: +# global.libraries <- c("foreign","devtools","rprojroot","ggplot2","nonsenseR") #*==============================================================================================*/ #* This is specific to AEA replication environment. May not be needed if no confidential data */ @@ -192,9 +188,11 @@ pkgTest <- function(x) ## Add any libraries to this line, and uncomment it. + results <- sapply(as.list(global.libraries), pkgTest) -# Return to the directory we started in +# lets get back to where we started + setwd(temphome) # keep these lines in the config file @@ -208,22 +206,3 @@ message(print(list.files(.libPaths()[1]))) message("Done with configuration.") -#################################### -# Run author code # -# # -#################################### - -#* Add author's programs in the order listed in the README - -author.programs <- c( - "master.R", - # "code/01_clean_data.R", - # "code/02_analysis.R" -) - -for (prog in author.programs) { - message(paste0("---- Sourcing: ", prog, " ----")) - source(file.path(rootdir, prog), echo = TRUE) -} - - From 350209b70a9f861eee1db45198f2028abf4c0b83 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 23 Jul 2026 02:12:10 -0600 Subject: [PATCH 8/9] fixed log file creation command --- template-Main.R | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/template-Main.R b/template-Main.R index 124bb2e..46cb790 100644 --- a/template-Main.R +++ b/template-Main.R @@ -9,7 +9,7 @@ # "touch .here" # If for some reason that does not work (and it always should) -# manually override in line 79 of this file. +# manually override in line 76 of this file. # Step 1: Script Order @@ -22,25 +22,22 @@ # Step 2: Packages # # If the README specifies packages that need to be manually installed, add them -# to readme.libraries on line 251. +# to readme.libraries on line 248. -# Step 3: Generate log file -# -# Once the code runs successfully, or if you need a log, run this to get a log file: -# The following command works on Linux, MacOS, and on Windows -# from the "Terminal" within Rstudio: -# R CMD BATCH master.R -# For alternative ways to do that, see -# https://github.com/labordynamicsinstitute/replicability-training/wiki/R-Tips - - -# Step 4: Make sure this script carries over +# Step 3: Make sure this script carries over # # Check any author scripts you're running for lines like rm(list = ls(all = TRUE)) # These will clear your environment and rootdir will no longer work. Comment these # lines out +# Step 4: Run code and generate log files +# +# From the Terminal (not Console) tab within Rstudio: +# R CMD BATCH --verbose --vanilla main.R main.$(date +%F_%H-%M-%S).Rout +# For alternative ways to do that, see +# https://github.com/labordynamicsinstitute/replicability-training/wiki/R-Tips + #*================================================ #* Let's do everything verbosely From 79aae49f5916ac7533209c2efdbd6d5d8b19fef8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 24 Jul 2026 01:22:42 -0600 Subject: [PATCH 9/9] updated file name, fixed rootdir instructions --- template-Main.R => template-main.R | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) rename template-Main.R => template-main.R (96%) diff --git a/template-Main.R b/template-main.R similarity index 96% rename from template-Main.R rename to template-main.R index 46cb790..1ecd0f7 100644 --- a/template-Main.R +++ b/template-main.R @@ -2,36 +2,36 @@ # INSTRUCTIONS: # -# Step 0: Bash setup +# Step 1: Packages +# +# If the README specifies packages that need to be manually installed, add them +# to readme.libraries on line 248. + +# Step 2: rootdir setup # -# In bash, set your working directory to where you're running this (probably 123456/code -# or similar) and type +# Identify the base directory of your replication package. If the author has an +#rproj file or a .here file, rootdir will be set there. Otherwise, in bash, set +# your working directory to the base directory, and type # "touch .here" - +# # If for some reason that does not work (and it always should) # manually override in line 76 of this file. -# Step 1: Script Order +# Step 3: Script order # # At the end of this file, add R scripts to author.programs in the order specified # in the README. If the author provides a main or master file, likely only that # file must be added. -# Step 2: Packages -# -# If the README specifies packages that need to be manually installed, add them -# to readme.libraries on line 248. - - -# Step 3: Make sure this script carries over +# Step 4: Make sure this script carries over # # Check any author scripts you're running for lines like rm(list = ls(all = TRUE)) # These will clear your environment and rootdir will no longer work. Comment these # lines out -# Step 4: Run code and generate log files +# Step 5: Run code and generate log files # # From the Terminal (not Console) tab within Rstudio: # R CMD BATCH --verbose --vanilla main.R main.$(date +%F_%H-%M-%S).Rout