usethis::edit_r_profile()
Day 1 Session 1: 👋 & The Whole Game
Invalid Date
This is a two-day, hands-on workshop for those who have embraced the tidyverse and want to build their own packages.
conf22
together!
Standing on the shoulders of Building Tidy Tools, rstudio::conf(2020) (C. Wickham and Wickham 2021), R Packages (H. Wickham and Bryan 2020)
conf22
together!
To each other! With help from Yorkshire!
Ingredients: Sugar, Glucose syrup, Cocoa mass, Vegetable fats (Palm, Rapeseed, Sunflower, Coconut,Mango kernel/ Sal/ Shea), Sweetened condensed skimmed milk (Skimmed milk, Sugar), Cocoa butter, Dried whole milk, Glucose-fructose syrup, Coconut, Lactose and proteins from whey (from Milk), Whey powder (from Milk), Hazelnuts, Skimmed milk powder, Butter (from Milk), Emulsifiers (Sunflower lecithin, E471), Flavourings, Butterfat (from Milk), Fat-reduced cocoa powder, Salt, Lactic acid.
Ingredients: Sugar, Semi-Sweet Chocolate (Sugar, Chocolate, Cocoa Butter, Milkfat, Soy and Sunflower Lecithin, Natural Vanilla Flavor), Glucose Syrup, Peppermint Oil, Citric Acid, Invertase.
Ingredients: Sugar, Glucose Syrup, Starch, Acids (Malic Acid, Citric Acid, Lactic Acid), Concentrated Fruit Juices (1%) (Apple, Grape, Blackcurrant, Orange, Lemon, Lime, Strawberry), Acidity Regulator (Trisodium Citrate), Flavourings, Naturally Sourced Colours (Anthocyanins, Copper Complexes of Chlorophyllins, Carotenes, Curcumin).
Full Code of Conduct & COVID. Please Review
Reporting:
conf@rstudio.com
conf22
together!
the TAs
colleagues, friends and learners at Schneider Electric, University of York and RForwards!
RStudio team and especially Mine Çetinkaya-Rundel
You need a laptop with the following installed:
devtools
and btt22
🎬 Detailed instructions for installing these are covered in Prerequisites
Time | Activity |
---|---|
09:00 - 10:30 | Session 1: Introduction & whole game |
10:30 - 11:00 | ☕ Coffee break |
11:00 - 12:30 | Session 2: Documentation - Minimal |
12:30 - 13:30 | 🍱 Lunch break |
13:30 - 15:00 | Session 3: Unit testing |
15:00 - 15:30 | ☕ Coffee break |
15:30 - 17:00 | Session 4: Documentation - Sharing |
Time | Activity |
---|---|
09:00 - 10:30 | Session 1: Function design |
10:30 - 11:00 | ☕ Coffee break |
11:00 - 12:30 | Session 2: Side effects |
12:30 - 13:30 | 🍱 Lunch break |
13:30 - 15:00 | Session 3: Tidy eval |
15:00 - 15:30 | ☕ Coffee break |
15:30 - 17:00 | Session 4: Functional and Object-Oriented Programming |
stickies
🟪 I’m all good, I’m done
🟧 I could do with some help
Discord
no stupid questions
🎬 Action! (today)
At the end of this section you will be able to:
.Rprofile
and RStudio set to ease the package writing processdevtools
(H. Wickham et al. 2021)
devtools::load_all()
devtools::check()
🎬 Tools | Global Options | General
🔲 Restore .RData into workspace at startup: unchecked
Save workspace to .RData on exit: Never
🎬 Tools | Global Options | Code | Display
☑️ Show margin: checked
Margin column 80
.Rprofile
The usethis
(H. Wickham, Bryan, and Barrett 2022) package allows you to add default information about you that will be used in package development.
🎬 Edit your .Rprofile
with usethis::edit_r_profile
:
usethis::edit_r_profile()
to set the following options….
.Rprofile
.Rprofile
🎬 Load devtools
and testthat
(H. Wickham 2011) on start up
if (interactive()) {
suppressMessages(require(devtools))
suppressMessages(require(testthat))
}
🎬 Restart R for these to take an effect.
DESCRIPTION
fileDESCRIPTION
, made available in NAMESPACE
fileRoxygen
commentsCRAN:
install.packages("praise")
GitHub:
remotes::install_github("rladies/praise")
Bioconductor
BiocManager::install("celaref")
In a library! In
R.home()
[1] "/opt/R/4.2.2/lib/R"
The R home directory is the top-level directory of your R installation.
Note: this is not the same as your working directory or your home directory.
list.files(R.home())
[1] "bin" "COPYING" "doc" "etc" "include"
[6] "lib" "library" "modules" "share" "SVN-REVISION"
.Library
[1] "/opt/R/4.2.2/lib/R/library"
dir(.Library)
[1] "base" "boot" "class" "cluster" "codetools"
[6] "compiler" "datasets" "foreign" "graphics" "grDevices"
[11] "grid" "KernSmooth" "lattice" "MASS" "Matrix"
[16] "methods" "mgcv" "nlme" "nnet" "parallel"
[21] "rpart" "spatial" "splines" "stats" "stats4"
[26] "survival" "tcltk" "tools" "translations" "utils"
ussie
packageussie
with a remote repo on GitHub.ussie
will allow you to work with European football league data supplied by the engsoccerdata
package (Curley 2016).
ussie
GitHub is the package in “Source” form
R/
man/
and vignettes/
There are five states a package can be in:
source
bundled
binary
installed
in-memory
source
bundled
binary
installed
in-memory
What you create and work on.
Specific directory structure with some particular components e.g., DESCRIPTION
, an R/
directory.
source
bundled
binary
installed
in-memory
Also known as “source tarballs”.
Package files compressed to single file.
Conventionally .tar.gz
You don’t normally need to make one.
Unpacked it looks very like the source package
source
bundled
binary
installed
in-memory
Package distribution for users w/o dev tools
Also a single file
Platform specific: .tgz
(Mac) .zip
(Windows)
Package developers submit a bundle to CRAN; CRAN makes and distributes binaries
source
bundled
binary
installed
in-memory
A binary package that’s been decompressed into a package library
Command line tool R CMD INSTALL
powers all package installation
source
bundled
binary
installed
in-memory
If a package is installed, library()
makes its function available by loading the package into memory and attaching it to the search path.
We do not use library()
for packages we are working on
devtools::load_all()
loads a source package directly into memory.
The CRAN version of engsoccerdata
has data from the start of the league until 2016 for england
, germany
, holland
, italy
and spain
BUT the format of the data is not the same for all countries!!
engsoccerdata
Rows: 192,004
Columns: 12
$ Date <fct> 1888-12-15, 1889-01-19, 1889-03-23, 1888-12-01, 1888-10-13, 1…
$ Season <dbl> 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1…
$ home <fct> Accrington F.C., Accrington F.C., Accrington F.C., Accrington…
$ visitor <fct> Aston Villa, Blackburn Rovers, Bolton Wanderers, Burnley, Der…
$ FT <fct> 1-1, 0-2, 2-3, 5-1, 6-2, 3-1, 1-2, 0-0, 2-0, 2-1, 4-4, 4-3, 6…
$ hgoal <dbl> 1, 0, 2, 5, 6, 3, 1, 0, 2, 2, 4, 4, 6, 6, 4, 4, 2, 9, 0, 5, 2…
$ vgoal <dbl> 1, 2, 3, 1, 2, 1, 2, 0, 0, 1, 4, 3, 1, 2, 2, 2, 1, 1, 2, 1, 0…
$ division <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ tier <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ totgoal <dbl> 2, 2, 5, 6, 8, 4, 3, 0, 2, 3, 8, 7, 7, 8, 6, 6, 3, 10, 2, 6, …
$ goaldif <dbl> 0, -2, -1, 4, 4, 2, -1, 0, 2, 1, 0, 1, 5, 4, 2, 2, 1, 8, -2, …
$ result <fct> D, A, A, H, H, H, A, D, H, H, D, H, H, H, H, H, H, H, A, H, H…
Rows: 23,915
Columns: 12
$ Date <chr> "1929-02-10", "1929-02-10", "1929-02-10", "1929-02-10", "1929-…
$ Season <dbl> 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928, 19…
$ home <chr> "Arenas de Getxo", "Espanyol Barcelona", "Real Madrid", "Real …
$ visitor <chr> "Atletico Madrid", "Real Union", "CE Europa", "Athletic Bilbao…
$ HT <chr> "0-2", "1-0", "0-0", "1-1", "0-0", "0-1", "3-0", "0-3", "0-1",…
$ FT <chr> "2-3", "3-2", "5-0", "1-1", "0-2", "1-2", "9-0", "0-3", "3-1",…
$ hgoal <dbl> 2, 3, 5, 1, 0, 1, 9, 0, 3, 5, 3, 3, 1, 0, 2, 1, 2, 3, 2, 2, 3,…
$ vgoal <dbl> 3, 2, 0, 1, 2, 2, 0, 3, 1, 2, 0, 1, 1, 4, 1, 2, 1, 0, 2, 0, 3,…
$ tier <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
$ round <chr> "league", "league", "league", "league", "league", "league", "l…
$ group <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ notes <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
So the first function in our ussie
package will turn these in to standard formats:
use only the common columns
give the same column the same data type
Be deliberate about where you create your package
Do not nest inside another RStudio project, R package or git repo.
🎬 Create a package:
usethis::create_package("~/Desktop/ussie")
✔ Creating 'ussie/'
✔ Setting active project to 'C:/Users/er13/OneDrive - University of York/Desktop/Desktop/rstudio-conf-2022/ussie'
✔ Creating 'R/'
✔ Writing 'DESCRIPTION'
Package: ussie
Title: What the Package Does (One Line, Title Case)
Version: 0.0.0.9000
Authors@R (parsed):
* Emma Rand <emma.rand@york.ac.uk> [aut, cre] (<https://orcid.org/0000-0002-1358-8275>)
Description: What the package does (one paragraph).
License: `use_mit_license()`, `use_gpl3_license()` or friends to
pick a license
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.0
✔ Writing 'NAMESPACE'
✔ Writing 'ussie.Rproj'
✔ Adding '^ussie\\.Rproj$' to '.Rbuildignore'
✔ Adding '.Rproj.user' to '.gitignore'
✔ Adding '^\\.Rproj\\.user$' to '.Rbuildignore'
✔ Opening 'C:/Users/er13/OneDrive - University of York/Desktop/Desktop/rstudio-conf-2022/ussie/' in new RStudio session
✔ Setting active project to '<no active project>'
create_package()
What happens when we run create_package()
?
R will create a folder called ussie
which is a package and an RStudio project
restart R in the new project
create some infrastructure for your package
start the RStudio Build pane
create_package()
What happens when we run create_package()
?
ussie.Rproj
DESCRIPTION
provides metadata about your package.
The R/
directory is where we will put .R
files with function definitions.
NAMESPACE
declares the functions your package exports and the functions your package imports from other packages.
create_package()
What happens when we run create_package()
?
.Rbuildignore
lists files that we need but that should not be included when building the R package from source.
.gitignore
anticipates Git usage and ignores some standard, behind-the-scenes files created by R and RStudio.
🎬 Make your package a git repository
usethis::use_git()
✔ Setting active project to 'C:/Users/er13/OneDrive - University of York/Desktop/Desktop/rstudio-conf-2022/ussie'
✔ Initialising Git repo
✔ Adding '.Rhistory', '.Rdata', '.httr-oauth', '.DS_Store' to '.gitignore'
There are 5 uncommitted files:
* '.gitignore'
* '.Rbuildignore'
* 'DESCRIPTION'
* 'NAMESPACE'
* 'ussie.Rproj'
Is it ok to commit them?
1: No way
2: Negative
3: I agree
🎬 Choose the option that means yes!
🎬 Choose the option that means yes!
Your session will restart.
🎬 Put on GitHub as a remote repository
usethis::use_github()
ℹ Defaulting to 'https' Git protocol
✔ Setting active project to 'C:/Users/er13/OneDrive - University of York/Desktop/Desktop/rstudio-conf-2022/ussie'
✔ Creating GitHub repository '3mmaRand/ussie'
✔ Setting remote 'origin' to 'https://github.com/3mmaRand/ussie.git'
✔ Setting URL field in DESCRIPTION to 'https://github.com/3mmaRand/ussie'
✔ Setting BugReports field in DESCRIPTION to 'https://github.com/3mmaRand/ussie/issues'
There is 1 uncommitted file:
* 'DESCRIPTION'
Is it ok to commit it?
1: Absolutely
2: Nope
3: No
🎬 Choose the option that means yes!
🎬 Quick check with:
usethis::git_sitrep()
Git config (global)
• Name: 'Emma Rand'
• Email: 'emma.rand@york.ac.uk'
• Global (user-level) gitignore file: 'C:/Users/er13/.gitignore'
• Vaccinated: TRUE
• Default Git protocol: 'https'
• Default initial branch name: 'master', 'main'
GitHub
• Default GitHub host: 'https://github.com'
• Personal access token for 'https://github.com': '<discovered>'
• GitHub user: '3mmaRand'
• Token scopes: 'gist, repo, user, workflow'
• Email(s): 'emma.rand@york.ac.uk (primary)', '7593411+3mmaRand@users.noreply.github.com'
Git repo for current project
• Active usethis project: 'C:/Users/er13/OneDrive - University of York/Desktop/Desktop/rstudio-conf-2022/ussie'
• Default branch: 'main'
• Current local branch -> remote tracking branch:
'main' -> 'origin/main'
GitHub remote configuration
• Type = 'ours'
• Host = 'https://github.com'
• Config supports a pull request = TRUE
• origin = '3mmaRand/ussie' (can push)
• upstream = <not configured>
• Desc = 'origin' is both the source and primary repo.
Read more about the GitHub remote configurations that usethis supports at:
'https://happygitwithr.com/common-remote-setups.html'
We will add uss_make_matches()
Functions will go in an .R
file.
There’s a usethis
helper for adding .R
files!
usethis::use_r()
🎬 Create a new R file in your package called matches.R
usethis::use_r("matches")
We want to be able to use the function like this: uss_make_matches(engsoccerdata::italy)
🎬 Put the following code into matches
:
uss_make_matches <- function(data_engsoc) {
result <-
data_engsoc |>
tibble::as_tibble() |>
dplyr::transmute(
tier = factor(tier, levels = c("1", "2", "3", "4")),
season = as.integer(Season),
date = as.Date(Date),
home = as.character(home),
visitor = as.character(visitor),
goals_home = as.integer(hgoal),
goals_visitor = as.integer(vgoal)
)
result
}
In a normal script you might use:
source("R/matches.R")
but when building packages we use a devtools
approach
devtools::load_all()
🎬 Load package with devtools::load_all()
.
devtools::load_all()
🎬 Try out the uss_make_matches()
function in the console.
uss_make_matches(engsoccerdata::italy)
# A tibble: 25,404 × 7
tier season date home visitor goals_home goals_visitor
<int> <int> <date> <chr> <chr> <int> <int>
1 1 1934 1934-09-30 Lazio… US Liv… 6 1
2 1 1934 1934-09-30 Torin… Unione… 3 1
3 1 1934 1934-09-30 Sampi… Bologn… 2 1
4 1 1934 1934-09-30 SSC N… US Ale… 0 1
5 1 1934 1934-09-30 ACF F… AS Roma 4 1
6 1 1934 1934-09-30 Bresc… Juvent… 0 2
7 1 1934 1934-09-30 Inter US Pal… 3 0
8 1 1934 1934-09-30 Pro V… AC Mil… 1 2
9 1 1934 1934-10-07 AC Mi… ACF Fi… 1 1
10 1 1934 1934-10-07 US Li… Inter 1 1
# … with 25,394 more rows
🤔 There’s no column for the country - that could be confusing
🎬 Change the function so it takes an additional argument which is the name of the country. The country name should be in column called “country”. The aim is to use the function like this:
uss_make_matches(engsoccerdata::spain, "Spain")
🎬 Load with devtools::load_all()
and try out the updated function.
uss_make_matches <- function(data_engsoc, country) {
result <-
data_engsoc |>
tibble::as_tibble() |>
dplyr::transmute(
country = as.character(country),
tier = factor(tier, levels = c("1", "2", "3", "4")),
season = as.integer(Season),
date = as.Date(Date),
home = as.character(home),
visitor = as.character(visitor),
goals_home = as.integer(hgoal),
goals_visitor = as.integer(vgoal)
)
result
}
Now would be a good time to commit your changes and push them to GitHub
R CMD check
is the gold standard for checking that an R package is in full working order.
It is a programme that is executed in the shell.
However, devtools
has the check()
function to allow you to run this without leaving your R session.
devtools::check()
🎬 Check your package:
devtools::check()
── R CMD check results ───────────────────────────────────── ussie 0.0.0.9000 ────
Duration: 25.1s
❯ checking DESCRIPTION meta-information ... WARNING
Non-standard license specification:
`use_mit_license()`, `use_gpl3_license()` or friends to pick a
license
Standardizable: FALSE
❯ checking dependencies in R code ... WARNING
'::' or ':::' imports not declared from:
'dplyr' 'tibble'
❯ checking R code for possible problems ... NOTE
uss_make_matches: no visible binding for global variable 'tier'
uss_make_matches: no visible binding for global variable 'Season'
uss_make_matches: no visible binding for global variable 'Date'
uss_make_matches: no visible binding for global variable 'home'
uss_make_matches: no visible binding for global variable 'visitor'
uss_make_matches: no visible binding for global variable 'hgoal'
uss_make_matches: no visible binding for global variable 'vgoal'
Undefined global functions or variables:
Date Season hgoal home tier vgoal visitor
0 errors ✔ | 2 warnings ✖ | 1 note ✖
man/
is created
On running devtools::check()
you may get an error if you are using a networked drive.
This is covered here and can be fixed.
Save a copy of this file:
Save it somewhere other than the ussie
directory
Open the file from the ussie
project session
Run the whole file
You should now find that check()
proceeds normally
── R CMD check results ───────────────────────────────────── ussie 0.0.0.9000 ────
Duration: 25.1s
❯ checking DESCRIPTION meta-information ... WARNING
Non-standard license specification:
`use_mit_license()`, `use_gpl3_license()` or friends to pick a
license
Standardizable: FALSE
❯ checking dependencies in R code ... WARNING
'::' or ':::' imports not declared from:
'dplyr' 'tibble'
❯ checking R code for possible problems ... NOTE
uss_make_matches: no visible binding for global variable 'tier'
uss_make_matches: no visible binding for global variable 'Season'
uss_make_matches: no visible binding for global variable 'Date'
uss_make_matches: no visible binding for global variable 'home'
uss_make_matches: no visible binding for global variable 'visitor'
uss_make_matches: no visible binding for global variable 'hgoal'
uss_make_matches: no visible binding for global variable 'vgoal'
Undefined global functions or variables:
Date Season hgoal home tier vgoal visitor
0 errors ✔ | 2 warnings ✖ | 1 note ✖
checking DESCRIPTION meta-information … WARNING
Non-standard license specification
✅ Next!
checking dependencies in R code … WARNING
‘::’ or ‘:::’ imports not declared
✅ Next!
no visible binding for global variables
✅ Tomorrow!
usethis
helps out again!
use_mit_license()
, use_agpl_license()
, use_ccby_license()
etc
🎬 Add a MIT license1 - use your own name!
usethis::use_mit_license("Emma Rand")
Read more in Choose a Licence.
use_mit_license()
🎬 What files have appeared?
🎬 How has the DESCRIPTION
file changed?
🎬 Run devtools::check()
again. Has one of the warnings disappeared?
Now would be a good time to commit your changes and push them to GitHub
devtools
devtools
DESCRIPTION
, NAMESPACE
, .Rbuildignore
.gitignore
R/
directory for functionsusethis:use_r()
devtools::load_all()
devtools::check()
to execute R CMD
checkusethis::use_mit_license()