• 1 Setup
  • 2 Objectives
  • 3 Problem
  • 4 For loop
  • 5 map2 & pmap

1 Setup

# Install packages 
if (!require("pacman")) install.packages("pacman")
## Loading required package: pacman
pacman::p_load(tidyverse, # tidyverse pkgs including purrr
               tictoc) # performance test 

2 Objectives

  • Learning how to use map2() and pmap() to avoid writing nested loops.

3 Problem

  • Problem: How can you create something like below?

[1] “University = Berkeley | Department = waterbenders”

[1] “University = Berkeley | Department = earthbenders”

[1] “University = Berkeley | Department = firebenders”

[1] “University = Berkeley | Department = airbenders”

[1] “University = Stanford | Department = waterbenders”

[1] “University = Stanford | Department = earthbenders”

[1] “University = Stanford | Department = firebenders”

[1] “University = Stanford | Department = airbenders”

  • The most manual way: You can copy and paste eight times.
paste("University = Berkeley | Department = CS")
## [1] "University = Berkeley | Department = CS"

4 For loop

  • A slightly more efficient way: using a for loop.

  • Think about which part of the statement is constant and which part varies ( = parameters).

  • Do we need a placeholder? No. We don’t need a placeholder because we don’t store the result of iterations.

Challenge 1: How many parameters do you need to solve the problem below?

- Fun fact: The department names are from [Avatar: The Last Airbender](https://en.wikipedia.org/wiki/Avatar:_The_Last_Airbender). 
# Outer loop 

for (univ in c("Berkeley", "Stanford")) {

  # Inner loop
  for (dept in c("waterbenders", "earthbenders", "firebenders", "airbenders")) {

    print(paste("University = ", univ, "|", "Department = ", dept))

  }

}
## [1] "University =  Berkeley | Department =  waterbenders"
## [1] "University =  Berkeley | Department =  earthbenders"
## [1] "University =  Berkeley | Department =  firebenders"
## [1] "University =  Berkeley | Department =  airbenders"
## [1] "University =  Stanford | Department =  waterbenders"
## [1] "University =  Stanford | Department =  earthbenders"
## [1] "University =  Stanford | Department =  firebenders"
## [1] "University =  Stanford | Department =  airbenders"
  • This is not bad, but … n arguments -> n nested for loops. As a scale of your problem grows, your code gets really complicated.

To become significantly more reliable, code must become more transparent. In particular, nested conditions and loops must be viewed with great suspicion. Complicated control flows confuse programmers. Messy code often hides bugs. — Bjarne Stroustrup

5 map2 & pmap

  • Step 1: Define inputs and a function.

Challenge 2 Why are we using rep() to create input vectors? For instance, for univ_list why not just use c("Berkeley", "Stanford")?

# Inputs (remember the length of these inputs should be identical)
univ_list <- rep(c("Berkeley", "Stanford"),4)

dept_list <- rep(c("waterbenders", "earthbenders", "firebenders", "airbenders"),2)

# Function 
print_lists <- function(univ, dept){
  
  print(paste("University = ", univ, "|", "Department = ", dept))
  
}

# Test 
print_lists(univ_list[1], dept_list[1])
## [1] "University =  Berkeley | Department =  waterbenders"
  • Step2: Using map2() or pmap()

# 2 arguments 
map2_output <- map2(univ_list, dept_list, print_lists) 
## [1] "University =  Berkeley | Department =  waterbenders"
## [1] "University =  Stanford | Department =  earthbenders"
## [1] "University =  Berkeley | Department =  firebenders"
## [1] "University =  Stanford | Department =  airbenders"
## [1] "University =  Berkeley | Department =  waterbenders"
## [1] "University =  Stanford | Department =  earthbenders"
## [1] "University =  Berkeley | Department =  firebenders"
## [1] "University =  Stanford | Department =  airbenders"

# 3+ arguments 
pmap_output <- pmap(list(univ_list, dept_list), print_lists) 
## [1] "University =  Berkeley | Department =  waterbenders"
## [1] "University =  Stanford | Department =  earthbenders"
## [1] "University =  Berkeley | Department =  firebenders"
## [1] "University =  Stanford | Department =  airbenders"
## [1] "University =  Berkeley | Department =  waterbenders"
## [1] "University =  Stanford | Department =  earthbenders"
## [1] "University =  Berkeley | Department =  firebenders"
## [1] "University =  Stanford | Department =  airbenders"

Challenge 3 Have you noticed that we used a slightly different input for pmap() compared to map() or map2()? What is the difference?