Project code is easier to move when scripts build paths from named parts instead of hard-coded host locations.

Program

Play the script to choose an output folder and see the relative path update.

folder_index
path_conventions.R
Replay: real traced execution (multi-file project)
root <- "analysis"
folders <- c("data", "figures", "reports")
folder_index <- 2
folder <- folders[folder_index]
path <- file.path(root, folder, "summary.csv")
cat(path, "\n", sep = "")
root <- "analysis"
folders <- c("data", "figures", "reports")
folder_index <- 1
folder <- folders[folder_index]
path <- file.path(root, folder, "summary.csv")
cat(path, "\n", sep = "")
root <- "analysis"
folders <- c("data", "figures", "reports")
folder_index <- 3
folder <- folders[folder_index]
path <- file.path(root, folder, "summary.csv")
cat(path, "\n", sep = "")
  1. root ← analysis

    1root <- "analysis"2folders <- c("data", "figures", "reports")
    values this stepanalysisroot
  2. folders ← data, figures, reports

    1root <- "analysis"2folders <- c("data", "figures", "reports")3folder_index <- 2
    values this stepdata, figures, reportsfolders
  3. folder_index ← 2

    2folders <- c("data", "figures", "reports")3folder_index <- 24folder <- folders[folder_index]
    values this step2folder_index
  4. folder ← figures

    3folder_index <- 24folder <- folders[folder_index]5path <- file.path(root, folder, "summary.csv")
    values this stepfiguresfolderdata, figures, reportsfolders2folder_index
  5. path ← analysis/figures/summary.csv

    4folder <- folders[folder_index]5path <- file.path(root, folder, "summary.csv")6cat(path, "\n", sep = "")
    values this stepanalysis/figures/summary.csvpathanalysisrootfiguresfolder
  6. cat(path, " ", sep = "")

    5path <- file.path(root, folder, "summary.csv")6cat(path, "\n", sep = "")
    outputanalysis/figures/summary.csv
    values this stepanalysis/figures/summary.csvpath
  1. root ← analysis

    1root <- "analysis"2folders <- c("data", "figures", "reports")
    values this stepanalysisroot
  2. folders ← data, figures, reports

    1root <- "analysis"2folders <- c("data", "figures", "reports")3folder_index <- 1
    values this stepdata, figures, reportsfolders
  3. folder_index ← 1

    2folders <- c("data", "figures", "reports")3folder_index <- 14folder <- folders[folder_index]
    values this step1folder_index
  4. folder ← data

    3folder_index <- 14folder <- folders[folder_index]5path <- file.path(root, folder, "summary.csv")
    values this stepdatafolderdata, figures, reportsfolders1folder_index
  5. path ← analysis/data/summary.csv

    4folder <- folders[folder_index]5path <- file.path(root, folder, "summary.csv")6cat(path, "\n", sep = "")
    values this stepanalysis/data/summary.csvpathanalysisrootdatafolder
  6. cat(path, " ", sep = "")

    5path <- file.path(root, folder, "summary.csv")6cat(path, "\n", sep = "")
    outputanalysis/data/summary.csv
    values this stepanalysis/data/summary.csvpath
  1. root ← analysis

    1root <- "analysis"2folders <- c("data", "figures", "reports")
    values this stepanalysisroot
  2. folders ← data, figures, reports

    1root <- "analysis"2folders <- c("data", "figures", "reports")3folder_index <- 3
    values this stepdata, figures, reportsfolders
  3. folder_index ← 3

    2folders <- c("data", "figures", "reports")3folder_index <- 34folder <- folders[folder_index]
    values this step3folder_index
  4. folder ← reports

    3folder_index <- 34folder <- folders[folder_index]5path <- file.path(root, folder, "summary.csv")
    values this stepreportsfolderdata, figures, reportsfolders3folder_index
  5. path ← analysis/reports/summary.csv

    4folder <- folders[folder_index]5path <- file.path(root, folder, "summary.csv")6cat(path, "\n", sep = "")
    values this stepanalysis/reports/summary.csvpathanalysisrootreportsfolder
  6. cat(path, " ", sep = "")

    5path <- file.path(root, folder, "summary.csv")6cat(path, "\n", sep = "")
    outputanalysis/reports/summary.csv
    values this stepanalysis/reports/summary.csvpath

Follow the Path

  1. root is analysis.
  2. folder_index starts at 2.
  3. folders[2] selects figures.
  4. file.path(root, folder, "summary.csv") joins the parts.
  5. The script prints analysis/figures/summary.csv. | folder_index | folder | output path | | ---: | --- | --- | | 1 | data | analysis/data/summary.csv | | 2 | figures | analysis/figures/summary.csv | | 3 | reports | analysis/reports/summary.csv |
relative path A project-relative path avoids host-specific prefixes.
file.path `file.path(root, folder, "summary.csv")` joins path parts portably.
convention Named folders make output locations explicit.

Exercise: path_conventions.R

Reproduce analysis/figures/summary.csv, then use folder_index 1 and 3 to predict analysis/data/summary.csv and analysis/reports/summary.csv.