2.6 Designed for Functional Programming
Functional Programming is an approach to replace iterative (i.e. for) loops. Consider the case where you may want two times the square root of the mpg
for each car in mtcars
. You could do this with a for loop as follows:
<- nrow(mtcars)
n <- rep(NA_real_, n)
roots for (car in 1:n) {
<- 2 * sqrt(mtcars$mpg[car])
roots[car] }
You could also write a function to do the computations. In functional programming, it’s important that the function does not have any side effects and the output only depends on the inputs. For example, the function my_sqrt()
takes in a car’s mpg and a weight by which to multiply the square root.
<- function(mpg, weight) {
my_sqrt * sqrt(mpg)
weight }
Using the purrr
package, we can forgo the for loop and use the map()
family of functions which use the basic syntax of map(vector, function)
. Below, we are applying the my_sqrt()
function, with a weight of 2, to the first three elements of mtcars$mpg
. User supplied functions can be declared by prefacing it with ~
(pronounced “twiddle”).
By default,
map()
returns a list.- If you know the class of a function’s output, you can use special suffixes. A character output, for example, would used by
map_chr()
, a double bymap_dbl()
, and a logical bymap_lgl()
.
- If you know the class of a function’s output, you can use special suffixes. A character output, for example, would used by
map(
.x = head(mtcars$mpg, 3),
~ my_sqrt(
mpg = .x,
weight = 2
) )
## [[1]]
## [1] 9.165151
##
## [[2]]
## [1] 9.165151
##
## [[3]]
## [1] 9.549869
map()
functions can be used with 2 inputs, by specifyingmap2()
- Requires arguments
.x
and.y
- Requires arguments
map2(
.x = head(mtcars$mpg, 3),
.y = c(1,2,3),
~ my_sqrt(
mpg = .x,
weight = .y
) )
## [[1]]
## [1] 4.582576
##
## [[2]]
## [1] 9.165151
##
## [[3]]
## [1] 14.3248