Higher-Order Functions in Package purrr

(Sections 14.3 - 14.4)

Packages

Make sure the following packages are attached:

library(tidyverse)
library(Lahman)

The purrr package is part of the tidyverse. It provides many higher-order functions.

Each higher-order function iterates over a given iterable data structure (vector, data frame, etc.) with the help of another given function.

map() and Variations

A Task

Suppose that we want to generate five vectors, each of which consists of a different given number of real numbers, randomly chosen between 0 and 1.

Solve With a Loop

vec <- c(5, 7, 8, 2, 9)
lst <- vector(mode = "list", length = length(vec))
for (i in seq_along(vec)) {
  lst[[i]] <- runif(vec[i])
}
lst
[[1]]
[1] 0.6469028 0.3942258 0.6185018 0.4768911 0.1360972

[[2]]
[1] 0.067384386 0.129152617 0.393117930 0.002582699 0.620205954 0.764414018
[7] 0.743835758

[[3]]
[1] 0.8261657 0.4227291 0.4092877 0.5396926 0.9607224 0.6535573 0.5467153
[8] 0.2660636

[[4]]
[1] 0.19679560 0.07787092

[[5]]
[1] 0.8183933 0.9424046 0.8842245 0.1658784 0.3551013 0.7480950 0.4509505
[8] 0.5558754 0.9640731

Solve with map()

how_many <- c(5, 7, 8, 2, 9)
lst <- 
  how_many %>%
  map(runif)
lst
[[1]]
[1] 0.6469028 0.3942258 0.6185018 0.4768911 0.1360972

[[2]]
[1] 0.067384386 0.129152617 0.393117930 0.002582699 0.620205954 0.764414018
[7] 0.743835758

[[3]]
[1] 0.8261657 0.4227291 0.4092877 0.5396926 0.9607224 0.6535573 0.5467153
[8] 0.2660636

[[4]]
[1] 0.19679560 0.07787092

[[5]]
[1] 0.8183933 0.9424046 0.8842245 0.1658784 0.3551013 0.7480950 0.4509505
[8] 0.5558754 0.9640731

How map() Works

map(.x, .f, ...)

In the template above:

  • .x can be a list or any atomic vector;
  • .f is a function that is to be applied to each element of .x.
  • ... consists of other arguments that are supplied as arguments for the .f function.

The result is always a list.

More Control

What if we want the random real numbers of be between 4 and 8?

No problem!

lst <- 
  how_many %>%
  map(runif, min = 4, max = 8)

What is This Code Doing?

lower_bounds <- 1:3
lower_bounds %>%
  map(runif, n = 2, max = 8)
[[1]]
[1] 3.008575 5.964877

[[2]]
[1] 6.514459 6.282105

[[3]]
[1] 6.688118 7.431739

How It Works

lower_bounds <- 1:3
lower_bounds %>%
  map(runif, n = 2, max = 8)
  • the .x argument is lower_bounds;
  • the .f argument is runif();
  • the n=2 becomes the first argument of runif();
  • the max = 8 becomes the max argument of runif();
  • so R deduces that the min parameter of runif() must iterate over lower_bounds!

Vary Two or More Parameters of a Function

Use pmap() for this:

how_many <- c(3,1,4)
upper_bounds <- c(1, 5, 10)
list(how_many, upper_bounds) %>%
  pmap(runif, min = 0)
[[1]]
[1] 0.4142409 0.5140328 0.6190231

[[2]]
[1] 0.193564

[[3]]
[1] 3.0889976 7.4509632 3.6170952 0.2348365

How This Works

how_many <- c(3,1,4)
upper_bounds <- c(1, 5, 10)
list(how_many, upper_bounds) %>%
  pmap(runif, min = 0)
  • The first argument of pmap() is called .l. This is set to list(how_many, upper_bounds), and they supply values for two arguments of runif().
  • min = 0 Takes care of the min parameter of runif().
  • So R deduces that how_many covers the n parameter, and upper_bounds covers the max parameter.

Why Not Vary All Three Parameters?

how_many <- c(3,1,4)
lower_bounds <- c(-5, 0, 5)
upper_bounds <- c(0, 5, 10)
args <- list(how_many, lower_bounds, upper_bounds)
args %>%
  pmap(runif)
[[1]]
[1] -0.007434684 -2.358819144 -3.901037909

[[2]]
[1] 1.012372

[[3]]
[1] 5.382376 9.158435 8.451728 9.673688

Write Your Own Helper Function

r_letters <- function(n, upper) {
  if (upper ) {
    sample(LETTERS, size = n, replace = TRUE)
  } else {
    sample(letters, size = n, replace = TRUE)
  }
}

Try It Out

r_letters(5, upper = TRUE)
[1] "O" "G" "A" "X" "S"
r_letters(4, upper = FALSE)
[1] "p" "m" "n" "u"

Now Map!

# vary number of letters to pick
n <- c(3, 6, 9)
# vary the case (upper, lower)
upper <- c(TRUE, FALSE, TRUE)  
list(n, upper) %>% 
  pmap(r_letters)
[[1]]
[1] "R" "I" "Q"

[[2]]
[1] "m" "d" "e" "y" "m" "o"

[[3]]
[1] "A" "O" "M" "C" "J" "I" "P" "V" "W"

Map with an Anonymous Function

c(1, 3, 5) %>% 
  map(function(x) runif(3, min = 0, max = x))
[[1]]
[1] 0.8951945 0.7801631 0.8545849

[[2]]
[1] 0.6993537 2.7956469 2.8740788

[[3]]
[1] 4.959646 2.544537 1.022301

Mapping With Data Frames

.x can be any object that can be coerced to a list. A data frame will do:

data("m111survey", package = "bcscr")
number_na <-
  m111survey %>% 
  map(function(col) sum(is.na(col)))
number_na
$height
[1] 0

$ideal_ht
[1] 2

$sleep
[1] 0

$fastest
[1] 0

$weight_feel
[1] 0

$love_first
[1] 0

$extra_life
[1] 0

$seat
[1] 0

$GPA
[1] 1

$enough_Sleep
[1] 0

$sex
[1] 0

$diff.ideal.act.
[1] 2

Options for Other Types of Output

When the result can take on a form other than a list, it is possible to use variants of map() such as:

  • map_int()
  • map_dbl()
  • map_lgl()
  • map_chr()

Example

number_na <-
  m111survey %>% 
  map_int(~ sum(is.na(.)))
number_na
         height        ideal_ht           sleep         fastest     weight_feel 
              0               2               0               0               0 
     love_first      extra_life            seat             GPA    enough_Sleep 
              0               0               0               1               0 
            sex diff.ideal.act. 
              0               2 

Another Example

Here are the types of each variable in m111survey:

m111survey %>% 
  map_chr(typeof)
         height        ideal_ht           sleep         fastest     weight_feel 
       "double"        "double"        "double"       "integer"       "integer" 
     love_first      extra_life            seat             GPA    enough_Sleep 
      "integer"       "integer"       "integer"        "double"       "integer" 
            sex diff.ideal.act. 
      "integer"        "double" 

Yet Another Example

Here is a statement of whether or not each variable is a factor:

m111survey %>% 
  map_lgl(is.factor)
         height        ideal_ht           sleep         fastest     weight_feel 
          FALSE           FALSE           FALSE           FALSE            TRUE 
     love_first      extra_life            seat             GPA    enough_Sleep 
           TRUE            TRUE            TRUE           FALSE            TRUE 
            sex diff.ideal.act. 
           TRUE           FALSE 

When Output is a List of Data Frames

We would like to produce a graph of the number of home-runs hit by each of the top five home-run hitters in the Major Leagues, for each season since 1900.

The Data

library(Lahman)
?Batting

A Helper Function

top_hr_hitters <- function(x, n) {
  x %>% 
    arrange(desc(HR)) %>% 
    select(playerID, yearID, HR) %>% 
    head(n)
}
Batting %>% 
  filter(yearID == 1927) %>% 
  top_hr_hitters(n = 10)
    playerID yearID HR
1   ruthba01   1927 60
2  gehrilo01   1927 47
3  willicy01   1927 30
4  wilsoha01   1927 30
5  hornsro01   1927 26
6  terrybi01   1927 20
7  bottoji01   1927 19
8  hafeych01   1927 18
9  lazzeto01   1927 18
10 willike01   1927 17

Split the Data

We need a list in which each element is a data frame covering a single season.

dplyr’s group_split() is our friend:

lst <-
  Batting %>% 
  filter(yearID >= 1900) %>% 
  select(playerID, yearID, HR) %>% 
  group_by(yearID) %>% 
  group_split()
str(lst)
list<tibble[,3]> [1:123] 
$ : tibble [195 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:195] "allenbo01" "baileha01" "barreji01" "barrysh01" ...
 ..$ yearID  : int [1:195] 1900 1900 1900 1900 1900 1900 1900 1900 1900 1900 ...
 ..$ HR      : int [1:195] 0 0 5 1 5 2 0 0 1 5 ...
$ : tibble [412 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:412] "anderjo01" "bakerbo01" "bakerbo01" "barreji01" ...
 ..$ yearID  : int [1:412] 1901 1901 1901 1901 1901 1901 1901 1901 1901 1901 ...
 ..$ HR      : int [1:412] 8 0 0 4 0 1 1 8 6 3 ...
$ : tibble [455 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:455] "adamsjo01" "adkindo01" "altroni01" "anderjo01" ...
 ..$ yearID  : int [1:455] 1902 1902 1902 1902 1902 1902 1902 1902 1902 1902 ...
 ..$ HR      : int [1:455] 0 0 0 4 0 2 0 3 4 3 ...
$ : tibble [400 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:400] "abbated01" "abbotfr01" "adkindo01" "altroni01" ...
 ..$ yearID  : int [1:400] 1903 1903 1903 1903 1903 1903 1903 1903 1903 1903 ...
 ..$ HR      : int [1:400] 1 1 0 0 0 0 2 0 0 0 ...
$ : tibble [406 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:406] "abbated01" "abbotfr01" "altroni01" "amesre01" ...
 ..$ yearID  : int [1:406] 1904 1904 1904 1904 1904 1904 1904 1904 1904 1904 ...
 ..$ HR      : int [1:406] 3 0 1 0 3 0 0 0 0 1 ...
$ : tibble [407 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:407] "abbated01" "abbotfr01" "ablesha01" "adamsri01" ...
 ..$ yearID  : int [1:407] 1905 1905 1905 1905 1905 1905 1905 1905 1905 1905 ...
 ..$ HR      : int [1:407] 3 0 0 0 0 0 0 1 0 2 ...
$ : tibble [437 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:437] "abstebi01" "adamsba01" "alperwh01" "altizda01" ...
 ..$ yearID  : int [1:437] 1906 1906 1906 1906 1906 1906 1906 1906 1906 1906 ...
 ..$ HR      : int [1:437] 0 0 3 1 0 0 3 0 2 2 ...
$ : tibble [447 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:447] "abbated01" "adamsba01" "alperwh01" "altizda01" ...
 ..$ yearID  : int [1:447] 1907 1907 1907 1907 1907 1907 1907 1907 1907 1907 ...
 ..$ HR      : int [1:447] 2 0 2 2 0 1 1 0 0 0 ...
$ : tibble [470 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:470] "abbated01" "alperwh01" "altizda01" "altizda01" ...
 ..$ yearID  : int [1:470] 1908 1908 1908 1908 1908 1908 1908 1908 1908 1908 ...
 ..$ HR      : int [1:470] 1 1 0 0 0 0 0 0 0 0 ...
$ : tibble [543 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:543] "abbated01" "ablesha01" "abstebi01" "adamsba01" ...
 ..$ yearID  : int [1:543] 1909 1909 1909 1909 1909 1909 1909 1909 1909 1909 ...
 ..$ HR      : int [1:543] 1 0 1 0 1 1 0 0 0 0 ...
$ : tibble [539 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:539] "abbated01" "abbated01" "abbotod01" "abstebi01" ...
 ..$ yearID  : int [1:539] 1910 1910 1910 1910 1910 1910 1910 1910 1910 1910 ...
 ..$ HR      : int [1:539] 0 0 0 0 0 0 0 0 0 0 ...
$ : tibble [567 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:567] "ablesha01" "adamsba01" "adamsbe01" "ainsmed01" ...
 ..$ yearID  : int [1:567] 1911 1911 1911 1911 1911 1911 1911 1911 1911 1911 ...
 ..$ HR      : int [1:567] 0 0 0 0 0 0 0 0 0 0 ...
$ : tibble [630 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:630] "adamsba01" "adamsbe01" "adamswi01" "aglerjo01" ...
 ..$ yearID  : int [1:630] 1912 1912 1912 1912 1912 1912 1912 1912 1912 1912 ...
 ..$ HR      : int [1:630] 0 0 0 0 0 0 0 2 0 1 ...
$ : tibble [616 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:616] "acostme01" "adamsba01" "adamswi01" "agnewsa01" ...
 ..$ yearID  : int [1:616] 1913 1913 1913 1913 1913 1913 1913 1913 1913 1913 ...
 ..$ HR      : int [1:616] 0 0 0 2 2 0 0 1 0 0 ...
$ : tibble [797 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:797] "acostme01" "adamsba01" "adamsda01" "adamska01" ...
 ..$ yearID  : int [1:797] 1914 1914 1914 1914 1914 1914 1914 1914 1914 1914 ...
 ..$ HR      : int [1:797] 0 1 1 0 0 0 0 0 0 0 ...
$ : tibble [796 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:796] "acostme01" "adamsba01" "adamsbe01" "adamsda01" ...
 ..$ yearID  : int [1:796] 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 ...
 ..$ HR      : int [1:796] 0 0 0 0 0 0 0 0 0 0 ...
$ : tibble [565 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:565] "acostme01" "adamsba01" "adamsbe01" "agnewsa01" ...
 ..$ yearID  : int [1:565] 1916 1916 1916 1916 1916 1916 1916 1916 1916 1916 ...
 ..$ HR      : int [1:565] 0 0 0 0 0 0 0 0 0 0 ...
$ : tibble [516 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:516] "adamsbe01" "agnewsa01" "ainsmed01" "aldrivi01" ...
 ..$ yearID  : int [1:516] 1917 1917 1917 1917 1917 1917 1917 1917 1917 1917 ...
 ..$ HR      : int [1:516] 1 0 0 0 1 0 0 0 0 0 ...
$ : tibble [506 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:506] "acostme01" "acostme01" "adamsba01" "adamsbe01" ...
 ..$ yearID  : int [1:506] 1918 1918 1918 1918 1918 1918 1918 1918 1918 1918 ...
 ..$ HR      : int [1:506] 0 0 0 0 0 0 0 0 0 0 ...
$ : tibble [534 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:534] "adamsba01" "adamsbe01" "adamswi01" "agnewsa01" ...
 ..$ yearID  : int [1:534] 1919 1919 1919 1919 1919 1919 1919 1919 1919 1919 ...
 ..$ HR      : int [1:534] 0 1 0 0 3 0 0 0 0 0 ...
$ : tibble [515 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:515] "acostjo01" "adamsba01" "ainsmed01" "alexape01" ...
 ..$ yearID  : int [1:515] 1920 1920 1920 1920 1920 1920 1920 1920 1920 1920 ...
 ..$ HR      : int [1:515] 0 1 1 1 0 0 1 0 1 0 ...
$ : tibble [520 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:520] "acostjo01" "adamsba01" "ainsmed01" "ainsmed01" ...
 ..$ yearID  : int [1:520] 1921 1921 1921 1921 1921 1921 1921 1921 1921 1921 ...
 ..$ HR      : int [1:520] 0 0 0 0 1 0 0 0 0 0 ...
$ : tibble [513 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:513] "acostjo01" "adamsba01" "adamssp01" "ainsmed01" ...
 ..$ yearID  : int [1:513] 1922 1922 1922 1922 1922 1922 1922 1922 1922 1922 ...
 ..$ HR      : int [1:513] 0 1 0 13 0 0 0 0 0 7 ...
$ : tibble [530 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:530] "abramge01" "adamsba01" "adamssp01" "adamssp02" ...
 ..$ yearID  : int [1:530] 1923 1923 1923 1923 1923 1923 1923 1923 1923 1923 ...
 ..$ HR      : int [1:530] 0 0 4 0 3 0 0 1 0 0 ...
$ : tibble [547 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:547] "adamsba01" "adamssp01" "ainsmed01" "aldrivi01" ...
 ..$ yearID  : int [1:547] 1924 1924 1924 1924 1924 1924 1924 1924 1924 1924 ...
 ..$ HR      : int [1:547] 0 1 0 0 1 0 0 0 1 0 ...
$ : tibble [557 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:557] "adamsba01" "adamsbo01" "adamssp01" "adamssp02" ...
 ..$ yearID  : int [1:557] 1925 1925 1925 1925 1925 1925 1925 1925 1925 1925 ...
 ..$ HR      : int [1:557] 0 0 2 0 1 2 0 0 0 0 ...
$ : tibble [526 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:526] "adamsba01" "adamssp01" "adamssp02" "aldrivi01" ...
 ..$ yearID  : int [1:526] 1926 1926 1926 1926 1926 1926 1926 1926 1926 1926 ...
 ..$ HR      : int [1:526] 0 0 0 0 0 0 0 0 0 0 ...
$ : tibble [541 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:541] "adamssp01" "adamssp02" "aldrivi01" "alexape01" ...
 ..$ yearID  : int [1:541] 1927 1927 1927 1927 1927 1927 1927 1927 1927 1927 ...
 ..$ HR      : int [1:541] 0 0 0 0 2 0 0 1 0 0 ...
$ : tibble [530 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:530] "adamssp01" "adkingr01" "aldrivi01" "alexape01" ...
 ..$ yearID  : int [1:530] 1928 1928 1928 1928 1928 1928 1928 1928 1928 1928 ...
 ..$ HR      : int [1:530] 0 0 1 1 1 0 0 0 1 0 ...
$ : tibble [530 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:530] "adamssp01" "adkingr01" "akersbi01" "alexada01" ...
 ..$ yearID  : int [1:530] 1929 1929 1929 1929 1929 1929 1929 1929 1929 1929 ...
 ..$ HR      : int [1:530] 0 0 1 25 0 6 0 0 0 0 ...
$ : tibble [531 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:531] "adamssp01" "akersbi01" "alexada01" "alexape01" ...
 ..$ yearID  : int [1:531] 1930 1930 1930 1930 1930 1930 1930 1930 1930 1930 ...
 ..$ HR      : int [1:531] 0 9 20 0 3 7 0 0 0 0 ...
$ : tibble [509 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:509] "adairji01" "adamsbo02" "adamssp01" "akersbi01" ...
 ..$ yearID  : int [1:509] 1931 1931 1931 1931 1931 1931 1931 1931 1931 1931 ...
 ..$ HR      : int [1:509] 0 0 1 0 3 5 0 0 0 0 ...
$ : tibble [527 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:527] "adamsbo02" "adamssp01" "akersbi01" "alexada01" ...
 ..$ yearID  : int [1:527] 1932 1932 1932 1932 1932 1932 1932 1932 1932 1932 ...
 ..$ HR      : int [1:527] 0 0 1 0 8 1 1 0 0 0 ...
$ : tibble [491 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:491] "adamssp01" "adamssp01" "alexada01" "allenet01" ...
 ..$ yearID  : int [1:491] 1933 1933 1933 1933 1933 1933 1933 1933 1933 1933 ...
 ..$ HR      : int [1:491] 0 1 5 0 0 1 0 0 0 6 ...
$ : tibble [521 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:521] "adamssp01" "allenet01" "allenjo02" "almadme01" ...
 ..$ yearID  : int [1:521] 1934 1934 1934 1934 1934 1934 1934 1934 1934 1934 ...
 ..$ HR      : int [1:521] 0 10 0 0 0 2 0 0 31 0 ...
$ : tibble [513 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:513] "allenet01" "allenjo02" "almadme01" "andreiv01" ...
 ..$ yearID  : int [1:513] 1935 1935 1935 1935 1935 1935 1935 1935 1935 1935 ...
 ..$ HR      : int [1:513] 8 1 3 0 1 0 19 0 0 0 ...
$ : tibble [511 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:511] "allenet01" "allenet01" "allenjo02" "almadme01" ...
 ..$ yearID  : int [1:511] 1936 1936 1936 1936 1936 1936 1936 1936 1936 1936 ...
 ..$ HR      : int [1:511] 1 3 0 1 0 0 0 0 6 0 ...
$ : tibble [526 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:526] "alexahu01" "allenbo03" "allenet01" "allenjo02" ...
 ..$ yearID  : int [1:526] 1937 1937 1937 1937 1937 1937 1937 1937 1937 1937 ...
 ..$ HR      : int [1:526] 0 0 0 0 1 4 0 0 0 0 ...
$ : tibble [530 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:530] "allenet01" "allenjo02" "almadme01" "almadme01" ...
 ..$ yearID  : int [1:530] 1938 1938 1938 1938 1938 1938 1938 1938 1938 1938 ...
 ..$ HR      : int [1:530] 0 1 1 3 0 0 0 0 0 4 ...
$ : tibble [579 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:579] "adamsbu01" "aderhmo01" "allenjo02" "almadme01" ...
 ..$ yearID  : int [1:579] 1939 1939 1939 1939 1939 1939 1939 1939 1939 1939 ...
 ..$ HR      : int [1:579] 0 1 0 1 0 0 0 0 0 0 ...
$ : tibble [541 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:541] "aderhmo01" "allenjo02" "anderre01" "andrena01" ...
 ..$ yearID  : int [1:541] 1940 1940 1940 1940 1940 1940 1940 1940 1940 1940 ...
 ..$ HR      : int [1:541] 0 0 0 0 0 0 0 0 0 0 ...
$ : tibble [582 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:582] "adamsac01" "aderhmo01" "albosed01" "alenoch01" ...
 ..$ yearID  : int [1:582] 1941 1941 1941 1941 1941 1941 1941 1941 1941 1941 ...
 ..$ HR      : int [1:582] 0 0 0 1 1 0 1 0 0 0 ...
$ : tibble [539 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:539] "abernte01" "abreujo01" "adamsac01" "adkinde01" ...
 ..$ yearID  : int [1:539] 1942 1942 1942 1942 1942 1942 1942 1942 1942 1942 ...
 ..$ HR      : int [1:539] 0 1 0 0 0 0 0 0 0 0 ...
$ : tibble [557 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:557] "abernte01" "adamsac01" "adamsbu01" "adamsbu01" ...
 ..$ yearID  : int [1:557] 1943 1943 1943 1943 1943 1943 1943 1943 1943 1943 ...
 ..$ HR      : int [1:557] 0 0 0 4 0 0 0 0 0 0 ...
$ : tibble [569 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:569] "abernte01" "adamsac01" "adamsbu01" "aderhmo01" ...
 ..$ yearID  : int [1:569] 1944 1944 1944 1944 1944 1944 1944 1944 1944 1944 ...
 ..$ HR      : int [1:569] 0 0 17 0 0 1 0 0 0 0 ...
$ : tibble [579 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:579] "adamsac01" "adamsbu01" "adamsbu01" "aderhmo01" ...
 ..$ yearID  : int [1:579] 1945 1945 1945 1945 1945 1945 1945 1945 1945 1945 ...
 ..$ HR      : int [1:579] 0 2 20 0 2 0 0 1 0 1 ...
$ : tibble [682 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:682] "abernwo01" "adamsac01" "adamsbo03" "adamsbu01" ...
 ..$ yearID  : int [1:682] 1946 1946 1946 1946 1946 1946 1946 1946 1946 1946 ...
 ..$ HR      : int [1:682] 0 0 4 5 0 0 0 2 0 0 ...
$ : tibble [582 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:582] "abernwo01" "aberscl01" "adamsbo03" "adamsbu01" ...
 ..$ yearID  : int [1:582] 1947 1947 1947 1947 1947 1947 1947 1947 1947 1947 ...
 ..$ HR      : int [1:582] 0 4 4 2 2 2 0 8 0 0 ...
$ : tibble [573 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:573] "aberscl01" "adamsbo03" "adamshe01" "anderan01" ...
 ..$ yearID  : int [1:573] 1948 1948 1948 1948 1948 1948 1948 1948 1948 1948 ...
 ..$ HR      : int [1:573] 1 1 0 1 0 0 0 5 2 0 ...
$ : tibble [573 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:573] "aberscl01" "abramca01" "adamsbo03" "adamshe01" ...
 ..$ yearID  : int [1:573] 1949 1949 1949 1949 1949 1949 1949 1949 1949 1949 ...
 ..$ HR      : int [1:573] 0 0 0 0 1 0 1 0 5 0 ...
$ : tibble [577 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:577] "aberal01" "abramca01" "adamsbo03" "adamshe01" ...
 ..$ yearID  : int [1:577] 1950 1950 1950 1950 1950 1950 1950 1950 1950 1950 ...
 ..$ HR      : int [1:577] 0 0 3 0 8 0 0 0 0 0 ...
$ : tibble [616 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:616] "abramca01" "adamsbo03" "adcocjo01" "addisbo01" ...
 ..$ yearID  : int [1:616] 1951 1951 1951 1951 1951 1951 1951 1951 1951 1951 ...
 ..$ HR      : int [1:616] 3 5 10 1 0 7 4 2 10 0 ...
$ : tibble [632 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:632] "abernbi01" "abramca01" "abramca01" "adamsbo03" ...
 ..$ yearID  : int [1:632] 1952 1952 1952 1952 1952 1952 1952 1952 1952 1952 ...
 ..$ HR      : int [1:632] 0 0 2 6 13 1 0 0 0 1 ...
$ : tibble [586 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:586] "aberal01" "aberal01" "abramca01" "adamsbo03" ...
 ..$ yearID  : int [1:586] 1953 1953 1953 1953 1953 1953 1953 1953 1953 1953 ...
 ..$ HR      : int [1:586] 0 0 15 8 18 0 0 0 0 1 ...
$ : tibble [576 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:576] "aaronha01" "aberal01" "abramca01" "abramca01" ...
 ..$ yearID  : int [1:576] 1954 1954 1954 1954 1954 1954 1954 1954 1954 1954 ...
 ..$ HR      : int [1:576] 13 0 0 6 3 23 11 3 4 0 ...
$ : tibble [655 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:655] "aaronha01" "aberal01" "abernte02" "abramca01" ...
 ..$ yearID  : int [1:655] 1955 1955 1955 1955 1955 1955 1955 1955 1955 1955 ...
 ..$ HR      : int [1:655] 27 0 0 6 2 0 15 0 0 0 ...
$ : tibble [621 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:621] "aaronha01" "aberal01" "abernte02" "abramca01" ...
 ..$ yearID  : int [1:621] 1956 1956 1956 1956 1956 1956 1956 1956 1956 1956 ...
 ..$ HR      : int [1:621] 26 0 0 0 0 0 38 0 0 16 ...
$ : tibble [615 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:615] "aaronha01" "aberal01" "aberal01" "abernte02" ...
 ..$ yearID  : int [1:615] 1957 1957 1957 1957 1957 1957 1957 1957 1957 1957 ...
 ..$ HR      : int [1:615] 44 0 0 0 0 1 12 0 0 0 ...
$ : tibble [638 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:638] "aaronha01" "ackerto01" "adairje01" "adamsbo03" ...
 ..$ yearID  : int [1:638] 1958 1958 1958 1958 1958 1958 1958 1958 1958 1958 ...
 ..$ HR      : int [1:638] 30 0 0 0 19 0 0 0 4 0 ...
$ : tibble [632 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:632] "aaronha01" "ackerto01" "adairje01" "adamsbo03" ...
 ..$ yearID  : int [1:632] 1959 1959 1959 1959 1959 1959 1959 1959 1959 1959 ...
 ..$ HR      : int [1:632] 39 0 0 0 25 0 30 10 12 0 ...
$ : tibble [637 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:637] "aaronha01" "abernte02" "adairje01" "adcocjo01" ...
 ..$ yearID  : int [1:637] 1960 1960 1960 1960 1960 1960 1960 1960 1960 1960 ...
 ..$ HR      : int [1:637] 40 0 1 25 0 15 8 0 13 0 ...
$ : tibble [698 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:698] "aaronha01" "adairje01" "adcocjo01" "aguirha01" ...
 ..$ yearID  : int [1:698] 1961 1961 1961 1961 1961 1961 1961 1961 1961 1961 ...
 ..$ HR      : int [1:698] 34 9 35 0 0 29 18 6 27 3 ...
$ : tibble [760 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:760] "aaronha01" "aaronto01" "adairje01" "adcocjo01" ...
 ..$ yearID  : int [1:760] 1962 1962 1962 1962 1962 1962 1962 1962 1962 1962 ...
 ..$ HR      : int [1:760] 45 8 11 29 0 0 12 0 29 25 ...
$ : tibble [752 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:752] "aaronha01" "aaronto01" "abernte02" "acklefr01" ...
 ..$ yearID  : int [1:752] 1963 1963 1963 1963 1963 1963 1963 1963 1963 1963 ...
 ..$ HR      : int [1:752] 44 1 0 0 6 13 0 1 0 9 ...
$ : tibble [754 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:754] "aaronha01" "abernte02" "acklefr01" "adairje01" ...
 ..$ yearID  : int [1:754] 1964 1964 1964 1964 1964 1964 1964 1964 1964 1964 ...
 ..$ HR      : int [1:754] 24 0 0 9 21 0 0 0 0 6 ...
$ : tibble [751 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:751] "aaronha01" "aaronto01" "abernte02" "adairje01" ...
 ..$ yearID  : int [1:751] 1965 1965 1965 1965 1965 1965 1965 1965 1965 1965 ...
 ..$ HR      : int [1:751] 32 0 0 7 14 0 0 0 0 0 ...
$ : tibble [774 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:774] "aaronha01" "abernte02" "abernte02" "adairje01" ...
 ..$ yearID  : int [1:774] 1966 1966 1966 1966 1966 1966 1966 1966 1966 1966 ...
 ..$ HR      : int [1:774] 44 0 0 0 4 18 0 22 0 0 ...
$ : tibble [786 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:786] "aaronha01" "abernte02" "adairje01" "adairje01" ...
 ..$ yearID  : int [1:786] 1967 1967 1967 1967 1967 1967 1967 1967 1967 1967 ...
 ..$ HR      : int [1:786] 39 0 0 3 0 1 14 0 0 0 ...
$ : tibble [715 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:715] "aaronha01" "aaronto01" "abernte02" "adairje01" ...
 ..$ yearID  : int [1:715] 1968 1968 1968 1968 1968 1968 1968 1968 1968 1968 ...
 ..$ HR      : int [1:715] 29 1 0 2 0 0 5 0 0 2 ...
$ : tibble [932 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:932] "aaronha01" "aaronto01" "abernte02" "adairje01" ...
 ..$ yearID  : int [1:932] 1969 1969 1969 1969 1969 1969 1969 1969 1969 1969 ...
 ..$ HR      : int [1:932] 44 1 0 5 0 0 26 0 0 0 ...
$ : tibble [919 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:919] "aaronha01" "aaronto01" "abernte02" "abernte02" ...
 ..$ yearID  : int [1:919] 1970 1970 1970 1970 1970 1970 1970 1970 1970 1970 ...
 ..$ HR      : int [1:919] 38 2 0 0 0 0 0 24 0 0 ...
$ : tibble [883 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:883] "aaronha01" "aaronto01" "abernte02" "acosted01" ...
 ..$ yearID  : int [1:883] 1971 1971 1971 1971 1971 1971 1971 1971 1971 1971 ...
 ..$ HR      : int [1:883] 47 0 0 0 14 0 0 4 23 1 ...
$ : tibble [889 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:889] "aaronha01" "abernte02" "acostcy01" "acosted01" ...
 ..$ yearID  : int [1:889] 1972 1972 1972 1972 1972 1972 1972 1972 1972 1972 ...
 ..$ HR      : int [1:889] 34 0 0 0 0 13 0 0 0 9 ...
$ : tibble [892 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:892] "aaronha01" "abbotgl01" "acostcy01" "adamsmi02" ...
 ..$ yearID  : int [1:892] 1973 1973 1973 1973 1973 1973 1973 1973 1973 1973 ...
 ..$ HR      : int [1:892] 40 0 0 3 8 3 0 0 0 0 ...
$ : tibble [914 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:914] "aaronha01" "abbotgl01" "acostcy01" "akerja01" ...
 ..$ yearID  : int [1:914] 1974 1974 1974 1974 1974 1974 1974 1974 1974 1974 ...
 ..$ HR      : int [1:914] 20 0 0 0 0 0 0 0 32 0 ...
$ : tibble [907 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:907] "aaronha01" "abbotgl01" "acostcy01" "adamsgl01" ...
 ..$ yearID  : int [1:907] 1975 1975 1975 1975 1975 1975 1975 1975 1975 1975 ...
 ..$ HR      : int [1:907] 12 0 0 4 0 0 0 0 12 0 ...
$ : tibble [886 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:886] "aaronha01" "abbotgl01" "adamsgl01" "adamsmi02" ...
 ..$ yearID  : int [1:886] 1976 1976 1976 1976 1976 1976 1976 1976 1976 1976 ...
 ..$ HR      : int [1:886] 10 0 0 0 0 0 0 0 2 0 ...
$ : tibble [984 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:984] "aasedo01" "abbotgl01" "adamsbo04" "adamsgl01" ...
 ..$ yearID  : int [1:984] 1977 1977 1977 1977 1977 1977 1977 1977 1977 1977 ...
 ..$ HR      : int [1:984] 0 0 2 6 0 0 0 1 0 5 ...
$ : tibble [960 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:960] "aasedo01" "abbotgl01" "adamsgl01" "adamsmi02" ...
 ..$ yearID  : int [1:960] 1978 1978 1978 1978 1978 1978 1978 1978 1978 1978 ...
 ..$ HR      : int [1:960] 0 0 7 0 0 0 10 17 0 0 ...
$ : tibble [961 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:961] "aasedo01" "abbotgl01" "adamsgl01" "aikenwi01" ...
 ..$ yearID  : int [1:961] 1979 1979 1979 1979 1979 1979 1979 1979 1979 1979 ...
 ..$ HR      : int [1:961] 0 0 8 21 2 0 15 0 0 3 ...
$ : tibble [950 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:950] "aasedo01" "abbotgl01" "adamsgl01" "aguaylu01" ...
 ..$ yearID  : int [1:950] 1980 1980 1980 1980 1980 1980 1980 1980 1980 1980 ...
 ..$ HR      : int [1:950] 0 0 6 1 20 0 0 5 0 0 ...
$ : tibble [944 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:944] "aasedo01" "abbotgl01" "adamsgl01" "agostju01" ...
 ..$ yearID  : int [1:944] 1981 1981 1981 1981 1981 1981 1981 1981 1981 1981 ...
 ..$ HR      : int [1:944] 0 0 2 0 1 17 0 0 1 0 ...
$ : tibble [992 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:992] "aasedo01" "adamsgl01" "adamsri02" "agostju01" ...
 ..$ yearID  : int [1:992] 1982 1982 1982 1982 1982 1982 1982 1982 1982 1982 ...
 ..$ HR      : int [1:992] 0 1 0 0 3 17 0 6 0 4 ...
$ : tibble [1,006 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1006] "abbotgl01" "abbotgl01" "ackerji01" "adamsri02" ...
 ..$ yearID  : int [1:1006] 1983 1983 1983 1983 1983 1983 1983 1983 1983 1983 ...
 ..$ HR      : int [1:1006] 0 0 0 2 0 0 0 23 0 0 ...
$ : tibble [984 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:984] "aasedo01" "abbotgl01" "ackerji01" "agostju01" ...
 ..$ yearID  : int [1:984] 1984 1984 1984 1984 1984 1984 1984 1984 1984 1984 ...
 ..$ HR      : int [1:984] 0 0 0 0 3 11 0 2 0 0 ...
$ : tibble [998 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:998] "aasedo01" "abregjo01" "ackerji01" "adamsri02" ...
 ..$ yearID  : int [1:998] 1985 1985 1985 1985 1985 1985 1985 1985 1985 1985 ...
 ..$ HR      : int [1:998] 0 0 0 2 0 6 0 1 0 0 ...
$ : tibble [1,017 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1017] "aasedo01" "ackerji01" "ackerji01" "adducji01" ...
 ..$ yearID  : int [1:1017] 1986 1986 1986 1986 1986 1986 1986 1986 1986 1986 ...
 ..$ HR      : int [1:1017] 0 0 0 0 0 0 4 2 0 2 ...
$ : tibble [1,048 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1048] "aasedo01" "abnersh01" "ackerji01" "afenitr01" ...
 ..$ yearID  : int [1:1048] 1987 1987 1987 1987 1987 1987 1987 1987 1987 1987 ...
 ..$ HR      : int [1:1048] 0 2 0 0 0 12 1 0 9 0 ...
$ : tibble [1,035 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1035] "aasedo01" "abnersh01" "ackerji01" "adducji01" ...
 ..$ yearID  : int [1:1035] 1988 1988 1988 1988 1988 1988 1988 1988 1988 1988 ...
 ..$ HR      : int [1:1035] 0 2 0 1 0 3 3 0 0 3 ...
$ : tibble [1,073 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1073] "aasedo01" "abbotji01" "abnersh01" "ackerji01" ...
 ..$ yearID  : int [1:1073] 1989 1989 1989 1989 1989 1989 1989 1989 1989 1989 ...
 ..$ HR      : int [1:1073] 0 0 2 0 0 0 0 1 0 0 ...
$ : tibble [1,115 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1115] "aasedo01" "abbotji01" "abbotpa01" "abnersh01" ...
 ..$ yearID  : int [1:1115] 1990 1990 1990 1990 1990 1990 1990 1990 1990 1990 ...
 ..$ HR      : int [1:1115] 0 0 0 1 0 0 0 0 0 0 ...
$ : tibble [1,086 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1086] "abbotji01" "abbotky01" "abbotpa01" "abnersh01" ...
 ..$ yearID  : int [1:1086] 1991 1991 1991 1991 1991 1991 1991 1991 1991 1991 ...
 ..$ HR      : int [1:1086] 0 0 0 1 2 0 0 0 0 0 ...
$ : tibble [1,066 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1066] "abbotji01" "abbotky01" "abbotpa01" "abnersh01" ...
 ..$ yearID  : int [1:1066] 1992 1992 1992 1992 1992 1992 1992 1992 1992 1992 ...
 ..$ HR      : int [1:1066] 0 0 0 1 0 0 0 0 0 0 ...
$ : tibble [1,180 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1180] "abbotji01" "abbotku01" "abbotpa01" "agostju01" ...
 ..$ yearID  : int [1:1180] 1993 1993 1993 1993 1993 1993 1993 1993 1993 1993 ...
 ..$ HR      : int [1:1180] 0 3 0 0 0 10 0 0 0 3 ...
$ : tibble [1,030 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1030] "abbotji01" "abbotku01" "acrema01" "aguilri01" ...
 ..$ yearID  : int [1:1030] 1994 1994 1994 1994 1994 1994 1994 1994 1994 1994 ...
 ..$ HR      : int [1:1030] 0 9 0 0 4 5 8 14 22 0 ...
$ : tibble [1,253 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1253] "abbotji01" "abbotji01" "abbotku01" "abbotky01" ...
 ..$ yearID  : int [1:1253] 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 ...
 ..$ HR      : int [1:1253] 0 0 17 0 0 0 0 0 0 0 ...
$ : tibble [1,253 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1253] "abbotji01" "abbotku01" "abbotky01" "abreubo01" ...
 ..$ yearID  : int [1:1253] 1996 1996 1996 1996 1996 1996 1996 1996 1996 1996 ...
 ..$ HR      : int [1:1253] 0 8 0 0 0 0 0 0 0 0 ...
$ : tibble [1,236 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1236] "abbotje01" "abbotku01" "abreubo01" "aceveju01" ...
 ..$ yearID  : int [1:1236] 1997 1997 1997 1997 1997 1997 1997 1997 1997 1997 ...
 ..$ HR      : int [1:1236] 1 6 3 0 0 0 0 0 0 0 ...
$ : tibble [1,322 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr [1:1322] "abbotje01" "abbotji01" "abbotku01" "abbotku01" ...
 ..$ yearID  : int [1:1322] 1998 1998 1998 1998 1998 1998 1998 1998 1998 1998 ...
 ..$ HR      : int [1:1322] 12 0 2 3 0 17 0 0 0 0 ...
 [list output truncated]
@ ptype: tibble [0 × 3] (S3: tbl_df/tbl/data.frame)
 ..$ playerID: chr(0) 
 ..$ yearID  : int(0) 
 ..$ HR      : int(0) 

All the Data

df <-
  lst %>% 
  ## make the list of data frames:
  map(top_hr_hitters, n = 5) %>% 
  ## purrr::list_rbind() makes one df from the list:
  list_rbind()

All at Once (With Chaining)!

Expand for Code
Batting %>%
  filter(yearID >= 1900) %>% 
  group_by(yearID) %>% 
  group_split() %>% 
  map(top_hr_hitters, n = 5) %>% 
  list_rbind() %>% 
  ggplot(aes(x = yearID, y = HR)) +
  geom_point(alpha = 0.5) +
  labs(x = NULL, y = "home runs")

walk() and Variations

walk()

  • walk() is similar to map().
  • But is used when we are interested in producing side-effects.
  • It applies its .f argument to each element of .x is was given,
  • but also returns the .x in case we want to pipe it into some other function.

A Silly Application

We will re-write an old function without using a for-loop:

pattern <- function(char = "*", n = 5) {
  line_length <- c(1:n, (n-1):1)
  the_line <- function(char, number) {
    cat(rep(char, times = number), "\n", sep = "")
  }
  line_length %>% walk(the_line, char = char)
}

Try It Out

pattern(char = "a", n = 4)
a
aa
aaa
aaaa
aaa
aa
a

Another Application: Saving Many Graphs

We would like to save plots of all numerical variables from the data frame m111survey, and also print summaries of them to the Console.

First we create a directory to hold the plots:

if (!dir.exists("plots")) dir.create("plots")

Names of the Variables We Want

Next, we get the names of the numerical variables in m111survey:

num_names <-
  m111survey %>% 
  keep(is.numeric) %>%   # purrr::keep()
  names()

The Variables Themselves

num_vars <-
  m111survey %>% 
  keep(is.numeric)

purrr::keep() keeps the columns that satisfy the given condition.

A Helper Function

save_graph <- function(var, varname) {
  p <-
    ggplot(data = NULL, aes(x = var)) +
    geom_density(fill = "burlywood") +
    labs(title = paste0(
      "Density plot for ",
      varname, ".")
    )
  ggsave(filename = paste0(
    "plots/density_", varname, ".png"),
    plot = p, device = "png"
  )
}

Try it out!

save_graph(m111survey$fastest, "fastest")

Another Helper Function

make_summary <- function(x, varname) {
  five <- fivenum(x, na.rm = TRUE)
  list(
    variable = varname,
       min = five[1],
       Q1 = five[2],
       median = five[3],
       Q3 = five[4],
       max = five[5]
  )
}

Try it out:

make_summary(x = m111survey$fastest, varname = "fastest")

The Results

$variable
[1] "fastest"

$min
[1] 60

$Q1
[1] 90.5

$median
[1] 102

$Q3
[1] 119.5

$max
[1] 190

Go For It!

list(num_vars, num_names) %>% 
  pwalk(save_graph) %>%  
  pmap_dfr(make_summary)
# A tibble: 6 × 6
  variable          min    Q1 median     Q3   max
  <chr>           <dbl> <dbl>  <dbl>  <dbl> <dbl>
1 height           51    65    68     71.8     79
2 ideal_ht         54    67    68     75       90
3 sleep             2     5     7      7       10
4 fastest          60    90.5 102    120.     190
5 GPA               1.9   2.9   3.22   3.56     4
6 diff.ideal.act.  -4     0     2      3       18

Check the plots Directory

It should contain these files:

  • density_diff.ideal.act.png
  • density_fastest.png
  • density.GPA.png
  • density_height.png
  • density_ideal_ht.png
  • density_sleep.png

Other purr Higher-Order Functions

keep()

keep() is similar to dplyr’s filter(), but whereas filter() chooses rows of a data frame based on a given conditions, keep() chooses the elements of the input list or vector .x based on a condition named .p.

Example

# keep the numbers that are 1 more than a multiple of 3
1:20 %>% 
  keep(.p = ~ . %% 3 == 1)
[1]  1  4  7 10 13 16 19

Another Example

# keep the factors in m111survey
m111survey %>% 
  keep(is.factor) %>% 
  str()
'data.frame':   71 obs. of  6 variables:
 $ weight_feel : Factor w/ 3 levels "1_underweight",..: 1 2 2 1 1 3 2 2 2 3 ...
 $ love_first  : Factor w/ 2 levels "no","yes": 1 1 1 1 1 1 1 1 1 1 ...
 $ extra_life  : Factor w/ 2 levels "no","yes": 2 2 1 1 2 1 2 2 2 1 ...
 $ seat        : Factor w/ 3 levels "1_front","2_middle",..: 1 2 2 1 3 1 1 3 3 2 ...
 $ enough_Sleep: Factor w/ 2 levels "no","yes": 1 1 1 1 1 2 1 2 1 2 ...
 $ sex         : Factor w/ 2 levels "female","male": 2 2 1 1 2 2 2 2 1 1 ...

discard()

discard(.x,, . p = condition) is equivalent to keep(.x, .p = !condition). Thus:

# discard numbers that are 1 more than a multiple of 3
1:20 %>% 
  discard(.p = ~ . %% 3 == 1)
 [1]  2  3  5  6  8  9 11 12 14 15 17 18 20

Another Example

# discard the factors in m111survey
m111survey %>% 
  discard(is.factor) %>% 
  str()
'data.frame':   71 obs. of  6 variables:
 $ height         : num  76 74 64 62 72 70.8 70 79 59 67 ...
 $ ideal_ht       : num  78 76 NA 65 72 NA 72 76 61 67 ...
 $ sleep          : num  9.5 7 9 7 8 10 4 6 7 7 ...
 $ fastest        : int  119 110 85 100 95 100 85 160 90 90 ...
 $ GPA            : num  3.56 2.5 3.8 3.5 3.2 3.1 3.68 2.7 2.8 NA ...
 $ diff.ideal.act.: num  2 2 NA 3 0 NA 2 -3 2 0 ...

reduce()

Given a vector .x and a function .f that takes two inputs, reduce() does the following:

  • applies f to elements 1 and 2 of .x, getting a result;
  • applies f to the result and to element 3 of .x, getting another result;
  • applies f to this new result and to element 4 of .x, getting yet another result …
  • … and so on until all of the elements of .x have been exhausted.
  • then reduce() returns the final result in the above series of operations.

Example

Suppose that you want to add up the elements of the vector:

vec <- c(3, 1, 4, 6)

Of course you could just use:

sum(vec)

But we will use reduce().

The Idea

  • add the 3 and 1 of (the first two elements of vec), getting 4;
  • then add 4 to 4, the third element of vec, getting 8;
  • then add 8 to 6, the final element of vec, getting 14;
  • then return 14.

Implement the Idea

vec %>%
  reduce(.f = sum)
[1] 14

Another Example: Intersection

A common application of reduce is to take an operation that is defined on only two items and extend it to operate on any number of items.

Consider the function intersect():

vec1 <- c(3, 4, 5, 6)
vec2 <- c(4, 6, 8, -4)
intersect(vec1, vec2)
[1] 4 6

Limitation of intersect()

You cannot intersect three or more vectors at once:

intersect(vec1, vec2, c(4, 7, 9))
Error in base::intersect(x, y, ...): unused argument (c(4, 7, 9))

reduce() to the Rescue!

lst <- list(
  c("Akash", "Bipan", "Chandra", "Devadatta", "Raj"),
  c("Raj", "Vikram", "Sita", "Akash", "Chandra"),
  c("Akash", "Raj", "Chandra", "Bipan", "Lila"),
  c("Akash", "Vikram", "Devadatta", "Raj", "Lila")
)
lst %>% 
  reduce(intersect)
[1] "Akash" "Raj"