Project Starter

Introduction

This vignette will walk you through the create_project() function. The function creates a new directory or populates an existing project directory with essential files needed for a new analysis project. Existing files in the directory will not be overwritten, unless the user specifically requests to overwrite them.

By default the directory is populated with customized README.md, .gitignore, and <name>.Rproj files. Users can also create a personalized project templates. Instructions for creating your own template is detailed in the custom templates section.

Default Template

Let’s create a new project and inspect the results. The new project will be created in a the folder called "My Project Folder".

# loading packages
library(starter)

# specifying project folder location (folder does not yet exist)
project_path <- fs::path(tempdir(), "My Project Folder")

Let’s set up our new project.

create_project(
  path = project_path,
  open = FALSE # don't open project in new RStudio session
)
#> ✔ Using "Default Project Template" template
#> ✔ Writing folder '/tmp/Rtmpg0QOL4/My Project Folder'
#> ✔ Writing files "README.md", ".gitignore", "My Project Folder.Rproj", and ".Rprofile"
#> ✔ Initialising Git repo
#> ✔ Initialising renv project
#> - Lockfile written to "/tmp/Rtmpg0QOL4/My Project Folder/renv.lock".
#> - renv infrastructure has been generated for project "/tmp/Rtmpg0QOL4/My Project Folder".

The directory was created, files added, a git repository was initialised in the folder, and the reproducible environment was constructed with the renv package.

README.md

The following is the README.md file added the project directory. It’s pre-filled with information specific to this project. The first line of the file is the project folder name, followed by a R code for creating a symbolic link from the project folder to the secure data folder.

# My Project Folder

# Symbolic Link to Secure Data
starter::create_symlink(to = "<secure data path>")

.gitignore

The .gitignore file is populated with various R files, data file types, and miscellaneous files typically not wanted in a Git repository.

# ignore R data files
.Rproj.user
.Rhistory
*.RData
*.rds
.Ruserdata
.Rapp.history
.Rhistory.RData

# Temporary files created by R markdown
*.utf8.md
*.knit.md

# ignore other types of data files
*.xlsx
*.xls
*.csv
*.dta
*.sas7bdat
*.sav
*.txt

# ignore data folder/symbolic link/sensitive file
data
secure_data
ext_data
tmp
env.json

# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
.httr-oauth

# ignore misc files
~*.docx
~*.xlsx
~*.pptx
~*.tmp
~*.rtf
Thumbs.db
.DS_Store
*.swp

# renv folders
renv/library/
renv/python/
renv/staging/

Custom Template

While the default template is useful, it can of course, be useful to create a custom template for yourself or your team. To create a custom template, you’ll need two things:

  1. Template files

  2. Meta data for each template file (e.g. location of template file, file name, etc.)

Template Files

There are two kinds of template files. The first are static files that a merely copied into the new project folder. The .gitignore file described above in the default template is an example of a file static file.

The second type of template file contain data or information specific to the new project. In the default template described above, the README.md file is an example of these dynamic template files. The README.md file is populated with the project name, and the project-specific code for creating a symbolic link to the secure data folder. The following fields are available to include in the dynamic templates.

{{folder_name}}          project folder name
{{folder_first_word}}    first word of folder name
{{symbolic_link}}        code for establishing symbolic link to data folder
{{foo()}}                any R function, e.g. `Sys.Date()`

Each of these fields are accessible via standard glue::glue() syntax, with the exception that double curly brackets are needed rather than single (e.g. glue::glue(., .open = "{{", .close = "}}")).

Below is an example of the dynamic README.md template from the default template.

# {{folder_name}}

# Symbolic Link to Secure Data
{{symbolic_link}}

Metadata

In order to create a template, you must add a metadata object that stores information about each template file. The metadata is stored as a named list: one element in the list per file in the template.

The list elements may be named any proper name within R. However, the names must be unique and we recommend short names. These do not need to match/reference any other text in the template file.

my_template <-
  list(
    gitignore = list(),
    readme = list(),
    rproj = list()
  )

Each element of the list is itself a list. The lists contain three important pieces of information about each template file.

  1. The template path and file name.

  2. The name of the file after it’s been copied to the new project folder.

  3. A logical argument indicating whether the file is a straight copy, or a dynamic file (described above).

The metadata for the README.md file in the default template looks like this:

readme <- 
  list(
    template_filename = system.file("project_templates/default_readme.md", package = "starter"), 
    filename = "README.md", 
    glue = TRUE
  )

Note that in this case, the location of the template file is pointing to a file location where the {starter} package is installed. If you are not saving your template in an R package, your template_file path will likely point to a folder in your machine, e.g. "C:/project_templates/default_readme.md"

As another example, here’s the metadata for the *.Rproj file from the default template. Note that the file name can be dynamic (the use of glue::glue()), while the underlying file is not dynamic (glue = FALSE). The list is stored as an expression so the template meta data is not evaluated until you call the create_project() function, allowing files to be dynamically named and template files to be saved within a package.

rproj <- 
  rlang::expr(list(
    template_filename = system.file("project_templates/default_rproj.Rproj", package = "starter"), 
    filename = glue::glue("{folder_name}.Rproj"), 
    glue = FALSE
  ))

Below is an example of a simple custom template.

my_template <- 
  list(
    readme = rlang::expr(list(
      template_filename = system.file("project_templates/default_readme.md", package = "starter"), 
      filename = "README.md",
      glue = TRUE
    )),
    rproj = rlang::expr(list(
      template_filename = system.file("project_templates/default_rproj.Rproj", package = "starter"), 
      filename = glue::glue("{folder_name}.Rproj"),
      glue = FALSE
    )),
    gitignore = rlang::expr(list(
      template_filename = system.file("project_templates/default_gitignore.txt", package = "starter"), 
      filename = ".gitignore", 
      glue = TRUE
    ))
  )

Note that you are able to put files into subfolders by including the subfolder name in the filename argument. This can be done for any type of file. Here’s an example of what the metadata could look like if the user has a static Rmarkdown template called template_analysis.Rmd that they want to copy into a project subfolder called scripts.

analysis <- 
  list(
    template_filename = "C:/project_templates/template_analysis.Rmd", 
    filename = "scripts/analysis.Rmd", 
    glue = FALSE
  )

Advanced Features

You may also source() an R script by adding the path to the file as a template attribute. The script will be sourced after project template has been placed. This feature is often used when you’d like to add an empty folder to your project.

attr(my_template, "script_path") <- "<path to file>"

Wrap the path to the script in an expression if you need to delay the evaluation of the path string.

You can also override the create_project() arguments by adding an attribute with a named list of the argument values you’d like the template to use. For example, if you always want to initialize the git repo and never use renv, attach this list list(git = TRUE, renv = FALSE) as an attribute called "arg_override".

There is one last step—give your template a label. The label will be displayed each time the template is called in either create_project() or use_project_file().

attr(my_template, "label") <- "My 1st Project Template"

It is recommended you create the list elements named 'readme' and 'gitignore'. The 'readme' element is used in the in the use_project_readme() function and 'gitignore' is in the use_project_gitignore() function—without these elements, these useful functions will return errors.

Implement Custom Template

Now that you have a folder with your template files stored and you have created a metadata list object, you can use them to create a new project folder with your custom template. The following code will get you started.

create_project(
  path = project_path,
  template = my_template # metadata list created above
)
#> ✔ Using "My 1st Project Template" template
#> ✔ Writing folder '/tmp/Rtmpg0QOL4/My Project Folder'
#> ✔ Writing files "README.md", "My Project Folder.Rproj", and ".gitignore"
#> ✔ Initialising Git repo
#> ✔ Initialising renv project
#> - Lockfile written to "/tmp/Rtmpg0QOL4/My Project Folder/renv.lock".
#> - renv infrastructure has been generated for project "/tmp/Rtmpg0QOL4/My Project Folder".