Packages, and How to Use Them Sparingly

SPEA V706 — Statistics for Research in Public Affairs

Coady Wing

The Plan

  • What is a package?

  • Installing and loading: install.packages(), library(), and pacman

  • Packages are kind of … bad.

    • But they can be good.
    • But remember they are bad
  • Approved stack of packages for this course

What is a package?

  • A bundle of functions someone else wrote, packaged so you can use it
  • It comes with documentation, help pages, and usually some example data
  • Packages add things base R does not do, or does slowly or confusingly, or whatever problem someone has with base R.

Installing a Package

install.packages("data.table")
  • Downloads it from CRAN and puts it in your library.

  • Installing does not make the functions available. It just puts them on the shelf

Loading a Package

library(data.table)
  • Takes it off the shelf and loads it into your session, so the functions are usable

Skipping the Load

data.table::fread("wages.csv")
  • package::function reaches into a package without loading it
  • Useful for one call, and useful when two packages have a function with the same name

Loading a bunch of packages, and checking that they are installed

if (!requireNamespace("data.table", quietly = TRUE)) {
  install.packages("data.table")
}
if (!requireNamespace("fixest", quietly = TRUE)) {
  install.packages("fixest")
}
if (!requireNamespace("ggplot2", quietly = TRUE)) {
  install.packages("ggplot2")
}
library(data.table)
library(fixest)
library(ggplot2)

This is fine. But a bit ugly looking.

pacman

pacman is a package for loading packages. It does the install-if-missing check for you.

# Load some packages using p_load
pacman::p_load(data.table, fixest, ggplot2, here)
  • p_load() installs any package that aren’t already installed, and then it loads them all.

Fancier is to make sure pacman itself is installed, and then use it to load the rest.

if (!requireNamespace("pacman", quietly = TRUE)) {
  install.packages("pacman")
}
pacman::p_load(data.table, fixest, ggplot2, here)

Packages are trouble

Are you trying to be a scientist?

  • Arthur C. Clarke – Any sufficiently advanced technology is indistinguishable from magic.

  • This is not Hogwarts.

  • We want to know how it all works. If your code feels like magic then go back and learn what it is doing.

The Transparency Problem

  • If a someone asks what you actually did to the data, you have to be able to answer.
  • “The package handled it” is not an answer that gets you published, gets you a job, gets you tenure.

Dependencies

A dependency is a package your code needs in order to work.

  • Packages sometimes have dependencies of their own.
    • When you install a package, you might also be installing a whole bunch of other packages.
  • A package might be updated over time, and the updates could change or break what your code does. Will your code still work in two years when you are at the last round of reviews?

Reproducibility

  • You want your code and results to be reproducible by other people in other years.
  • Packages can be a problem for reproducibility
    • Store the current version of the packages in your project and include them in the replication kit.

Package Minimalism

Our rule: do not use a package unless you need it.

  • For assignments in this course, package use is regulated and generally discouraged

  • Stick to the approved stack below, and ask if you want something else

  • This is a teaching rule but I follow this rule in my own work.

The Approved Stack

Packages we like, a bit.

  • Six approved packages.

  • But it’s really three important ones. The other three are convenient and/or handy for later-in-your-life.

Six Approved Packages

Package Job
data.table Reading, filtering, reshaping, summarizing data
fixest Regressions
ggplot2 Graphics
collapse Fast grouped operations, when you need the speed
pacman Loads the others, installing anything missing
here Builds file paths from the project root
  • data.table, fixest, and ggplot2 are really helpful.
  • collapse is a speed booster for big data.
  • pacman and here are convenience packages but I like them because they help you make your code more portable, which is a noble goal.

here and the Project Root

The problem: this path works on exactly one computer.

# bad
dt <- fread("/Users/cwing/Dropbox/projects/wages/raw_data/wages.csv")
# good
dt <- fread(here("raw_data", "wages.csv"))
  • here() finds your project’s root folder, then builds the path down from there
  • The same line works on your laptop, your coauthor’s laptop, and the cluster

What here() Keys Off

  • here() looks upward from where you are until it finds a marker of the project root
  • The usual marker is an .Rproj file, which RStudio creates for you
  • File → New Project in RStudio makes the folder and drops the .Rproj in it
here()
#> [1] "/Users/you/projects/wages"

here("raw_data", "wages.csv")
#> [1] "/Users/you/projects/wages/raw_data/wages.csv"

Don’t hardcode paths using setwd().

fixest

Regression in Base R

Base R fits a regression using lm(), which is perfectly good.

data(mtcars)

fit <- lm(mpg ~ wt + hp, data = mtcars)
summary(fit)
  • mpg ~ wt + hp is a formula: outcome on the left, regressors on the right
  • summary() prints coefficients, standard errors, and the usual fit statistics

fixest is a package for regression that is faster and more flexible for big data, fixed effects, cluster robust inference, etc.

pacman::p_load(fixest)

est <- feols(mpg ~ wt + hp, data = mtcars)
est
  • feols() takes the same formula and gives the same coefficients
  • You don’t need most of it’s functionality until later. But it’s fine to learn it now.

ggplot2

It makes graphs using a grammar of graphics: you build a plot by adding layers, and every plot follows the same shape.

pacman::p_load(ggplot2)

# economics ships with ggplot2: US macro data, monthly
p <- ggplot(economics, aes(x = date, y = psavert)) +
  geom_line(colour = "#000080", linewidth = 1) +
  labs(x = NULL, y = "Personal saving rate (%)",
       title = "US personal saving rate, 1967-2015")

p

The Result

Reading the Grammar

ggplot(economics, aes(x = date, y = psavert)) +
  geom_line()
  • ggplot(data, aes(...)) says which data, and which columns map to which axes
  • aes() is the aesthetic mapping: x, y, colour, shape
  • geom_line() says draw it as a line. geom_point() for a scatter, geom_col() for bars

Saving a Plot

p <- ggplot(economics, aes(x = date, y = psavert)) +
  geom_line()

ggsave(here("outputs", "figures", "savings_rate.png"),
       p, width = 8, height = 5)
  • Build the plot into an object, then save the object.
  • Always give width and height, or the size depends on whatever window was open

data.table

pacman::p_load(data.table)

dt <- fread(here("raw_data", "wages.csv"))

dt[educ >= 16, .(avg_wage = mean(wage)), by = female]
  • The do-it-all package for data: read, filter, compute, group, reshape, merge
  • One syntax covers a lot of ground: dt[i, j, by]
  • Great for large data sets.
  • We have a whole slide deck on data.table.

collapse

pacman::p_load(collapse)

fmean(dt$wage, g = dt$industry)   # group means, very fast
  • Fast grouped statistics, aimed squarely at big panels
# summarize the data    
qsu(dt)

Recap

  • A package is borrowed code that

  • Packages hide mechanics and drag in dependencies, which costs you learning and reproducibility

  • Be a minimalist: pacman, here, data.table, fixest, ggplot2, collapse, and ask before adding more