Announcement Icon Online training class for Clinical R programming batch starts on Monday, 02Feb2026. Click here for details.

Run multiple programs from a single file


Lesson Description
-

Steps to replicate this lesson:

  • Save all the supplied R files into a single folder on our system (for example, r_batch_xpt_example).
  • Inside that folder, create a subfolder named programs and place each individual R program there (01_make_dm_xpt.R, 02_make_ae_xpt.R, 03_make_lb_xpt.R).
  • Keep the batch driver file run_all.R in the root of the same folder (at the same level as the programs folder).
  • At the top of each individual R program, add library(tidyverse) so that the pipe operator %>% and tidyverse functions are available during batch execution.
  • Remember that in batch mode (Rscript), no packages are loaded automatically, so library(tidyverse) must be explicitly stated in every program that uses tidyverse syntax.
  • Each individual program should be fully self-contained, meaning it should read data, process it, and write its own XPT file without relying on objects created by other programs.
  • Confirm that each program creates the required output folders (output/xpt and output/logs) using dir.create(), so manual folder creation is not required.
  • To run all programs in batch (similar to SAS batch submission), open a command prompt or terminal and navigate to the folder that contains run_all.R.
  • Execute the batch driver using Rscript run_all.R.
  • The batch driver will run each individual R program one by one in a clean R session, similar to submitting multiple SAS programs in sequence.
  • After execution, verify that the XPT files are created in the output/xpt folder (for example, DM.xpt, AE.xpt, LB.xpt).
  • Review the output/logs folder to check the log file corresponding to each program, which serves the same purpose as individual SAS log files.
  • If any program fails, open its specific log file, fix the issue in that program, and rerun Rscript run_all.R to execute the full batch again.
  • To add a new program to the batch, create a new R file in the programs folder (for example, 04_make_ex_xpt.R) and add its filename to the scripts list inside run_all.R so it is included in the batch run.

sas - code - here

#==============================================================================
#01_make_dm_xpt.R
# Create DM.xpt
#==============================================================================
library(tidyverse)

out_dir <- file.path("output", "xpt")
dir.create(out_dir, recursive = TRUE, showWarnings = FALSE)

dm <- tibble::tribble(
  ~studyid, ~domain, ~usubjid,        ~subjid, ~sex, ~age,
  "CSG001", "DM",    "CSG001-0001",    "0001",  "M",   35,
  "CSG001", "DM",    "CSG001-0002",    "0002",  "F",   29
)

dm <- dm %>%
  dplyr::mutate(
    dplyr::across(where(is.character), ~ stringr::str_sub(.x, 1, 200))
  )

haven::write_xpt(dm, file.path(out_dir, "DM.xpt"))



#==============================================================================
#02_make_ae_xpt.R
# Create AE.xpt
#==============================================================================
library(tidyverse)

out_dir <- file.path("output", "xpt")
dir.create(out_dir, recursive = TRUE, showWarnings = FALSE)

ae <- tibble::tribble(
  ~studyid, ~domain, ~usubjid,        ~aeseq, ~aeterm, ~aeser,
  "CSG001", "AE",    "CSG001-0001",        1, "Headache", "N",
  "CSG001", "AE",    "CSG001-0002",        1, "Nausea",   "N"
)

ae <- ae %>%
  dplyr::mutate(
    dplyr::across(where(is.character), ~ stringr::str_sub(.x, 1, 200))
  )

haven::write_xpt(ae, file.path(out_dir, "AE.xpt"))



#==============================================================================
#03_make_lb_xpt.R
# Create LB.xpt
#==============================================================================
library(tidyverse)

out_dir <- file.path("output", "xpt")
dir.create(out_dir, recursive = TRUE, showWarnings = FALSE)

lb <- tibble::tribble(
  ~studyid, ~domain, ~usubjid, ~lbtestcd, ~lbtest, ~lbstresn, ~lbstresu,
  "CSG001", "LB",    "CSG001-0001", "HGB", "Hemoglobin", 13.2, "g/dL"
)

lb <- lb %>%
  dplyr::mutate(
    dplyr::across(where(is.character), ~ stringr::str_sub(.x, 1, 200))
  )

haven::write_xpt(lb, file.path(out_dir, "LB.xpt"))




#==============================================================================
#run_all.R
# Batch runner (SAS-style batch submit)
#==============================================================================

setwd("C:/Users/curio/Downloads/r_batch_xpt_example")

library(tidyverse)

scripts <- c(
  file.path("programs", "01_make_dm_xpt.R"),
  file.path("programs", "02_make_ae_xpt.R"),
  file.path("programs", "03_make_lb_xpt.R")
)

log_dir <- file.path("output", "logs")
dir.create(log_dir, recursive = TRUE, showWarnings = FALSE)

for (s in scripts) {
  log_file <- file.path(
    log_dir,
    paste0(tools::file_path_sans_ext(basename(s)), ".log")
  )

  system2(
    command = "Rscript",
    args = s,
    stdout = log_file,
    stderr = log_file
  )
}

cat("Batch run completed/n")
  • This program acts as the batch driver, similar to submitting multiple SAS programs in sequence.
  • We first set the working directory so that all relative paths (programs, output, logs) resolve correctly during batch execution.
  • We load tidyverse so that any tidyverse utilities used inside this driver script are available (even though individual programs run in separate R sessions).
  • A character vector named scripts is created, listing the R programs to be executed, in the exact order we want them to run, similar to ordering SAS programs.
  • Each entry in the scripts vector points to one R program stored inside the programs folder.
  • We define a logs folder (output/logs) and create it if it does not already exist, ensuring that log files can be written without manual setup.
  • The for loop iterates over each R program listed in the scripts vector, submitting them one by one.
  • For each program, a corresponding log file name is constructed using the program name, so every program has its own log file.
  • The system2() function is used to call Rscript, which runs each R program in a fresh R session, similar to submitting each SAS program independently in batch mode.
  • Standard output and error messages from each program are redirected into its respective log file, closely mimicking SAS log behavior.
  • Once all programs have been executed, a completion message is printed to indicate that the batch run has finished.
  • This approach ensures clean isolation between programs, predictable execution order, and clear log tracking, making it suitable for production-style clinical programming workflows.