A functional is a function that takes a function as an input and returns a vector as output.
Hadley Wickham, Advanced R
statistic <- function(f){ data <- c(10, 20, 30, 40, 62, 63) f(data)}
statistic(mean)
[1] 37.5
statistic(sum)
[1] 225
lapply: loop over a list and evaluate a function on each element.
x <- list( a = 1:8, b = c(2.1, 3.2, 4.2, 5, 6))x
$a[1] 1 2 3 4 5 6 7 8$b[1] 2.1 3.2 4.2 5.0 6.0
#We are passing `mean` is an argument to lapplylapply(x, mean)
$a[1] 4.5$b[1] 4.1
lapply(x, sum)
$a[1] 36$b[1] 20.5
cv <- function(data){sd(data)/mean(data)}lapply(x, cv)
$a[1] 0.5443311$b[1] 0.3706996
x <- list( a = 1:8, b = c(2.1, 3.2, 4.2, 5, 6))x
$a[1] 1 2 3 4 5 6 7 8$b[1] 2.1 3.2 4.2 5.0 6.0
result_x <- list()result_x
list()
for (i in 1:2){ result_x[[i]] <- mean(x[[i]])}result_x
[[1]][1] 4.5[[2]][1] 4.1
lapply: loop over a list and evaluate a function on each element.
x <- list( a = 1:8, b = c(2.1, 3.2, 4.2, 5, 6))x
$a[1] 1 2 3 4 5 6 7 8$b[1] 2.1 3.2 4.2 5.0 6.0
#We are passing `mean` is an argument to lapplysapply(x, mean)
a b 4.5 4.1
sapply(x, sum)
a b 36.0 20.5
Same as lapply
but the output is a vector.
map()
function in purrrlibrary(purrr)
x <- list( a = 1:8, b = c(2.1, 3.2, 4.2, 5, 6))x
$a[1] 1 2 3 4 5 6 7 8$b[1] 2.1 3.2 4.2 5.0 6.0
map(x, mean)
$a[1] 4.5$b[1] 4.1
map()
is lapply()
.map
syntaxmap(YOUR_LIST, YOUR_FUNCTION)
map(c(4, 9, 16), sqrt)
[[1]][1] 2[[2]][1] 3[[3]][1] 4
map()
iris_species <- split(iris, iris$Species)str(iris_species)
List of 3 $ setosa :'data.frame': 50 obs. of 5 variables: ..$ Sepal.Length: num [1:50] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... ..$ Sepal.Width : num [1:50] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... ..$ Petal.Length: num [1:50] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... ..$ Petal.Width : num [1:50] 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... ..$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ... $ versicolor:'data.frame': 50 obs. of 5 variables: ..$ Sepal.Length: num [1:50] 7 6.4 6.9 5.5 6.5 5.7 6.3 4.9 6.6 5.2 ... ..$ Sepal.Width : num [1:50] 3.2 3.2 3.1 2.3 2.8 2.8 3.3 2.4 2.9 2.7 ... ..$ Petal.Length: num [1:50] 4.7 4.5 4.9 4 4.6 4.5 4.7 3.3 4.6 3.9 ... ..$ Petal.Width : num [1:50] 1.4 1.5 1.5 1.3 1.5 1.3 1.6 1 1.3 1.4 ... ..$ Species : Factor w/ 3 levels "setosa","versicolor",..: 2 2 2 2 2 2 2 2 2 2 ... $ virginica :'data.frame': 50 obs. of 5 variables: ..$ Sepal.Length: num [1:50] 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3 6.7 7.2 ... ..$ Sepal.Width : num [1:50] 3.3 2.7 3 2.9 3 3 2.5 2.9 2.5 3.6 ... ..$ Petal.Length: num [1:50] 6 5.1 5.9 5.6 5.8 6.6 4.5 6.3 5.8 6.1 ... ..$ Petal.Width : num [1:50] 2.5 1.9 2.1 1.8 2.2 2.1 1.7 1.8 1.8 2.5 ... ..$ Species : Factor w/ 3 levels "setosa","versicolor",..: 3 3 3 3 3 3 3 3 3 3 ...
This creates a list of three data frames.
map()
(cont.)head(iris_species)
$setosa Sepal.Length Sepal.Width Petal.Length Petal.Width Species1 5.1 3.5 1.4 0.2 setosa2 4.9 3.0 1.4 0.2 setosa3 4.7 3.2 1.3 0.2 setosa4 4.6 3.1 1.5 0.2 setosa5 5.0 3.6 1.4 0.2 setosa6 5.4 3.9 1.7 0.4 setosa7 4.6 3.4 1.4 0.3 setosa8 5.0 3.4 1.5 0.2 setosa9 4.4 2.9 1.4 0.2 setosa10 4.9 3.1 1.5 0.1 setosa11 5.4 3.7 1.5 0.2 setosa12 4.8 3.4 1.6 0.2 setosa13 4.8 3.0 1.4 0.1 setosa14 4.3 3.0 1.1 0.1 setosa15 5.8 4.0 1.2 0.2 setosa16 5.7 4.4 1.5 0.4 setosa17 5.4 3.9 1.3 0.4 setosa18 5.1 3.5 1.4 0.3 setosa19 5.7 3.8 1.7 0.3 setosa20 5.1 3.8 1.5 0.3 setosa21 5.4 3.4 1.7 0.2 setosa22 5.1 3.7 1.5 0.4 setosa23 4.6 3.6 1.0 0.2 setosa24 5.1 3.3 1.7 0.5 setosa25 4.8 3.4 1.9 0.2 setosa26 5.0 3.0 1.6 0.2 setosa27 5.0 3.4 1.6 0.4 setosa28 5.2 3.5 1.5 0.2 setosa29 5.2 3.4 1.4 0.2 setosa30 4.7 3.2 1.6 0.2 setosa31 4.8 3.1 1.6 0.2 setosa32 5.4 3.4 1.5 0.4 setosa33 5.2 4.1 1.5 0.1 setosa34 5.5 4.2 1.4 0.2 setosa35 4.9 3.1 1.5 0.2 setosa36 5.0 3.2 1.2 0.2 setosa37 5.5 3.5 1.3 0.2 setosa38 4.9 3.6 1.4 0.1 setosa39 4.4 3.0 1.3 0.2 setosa40 5.1 3.4 1.5 0.2 setosa41 5.0 3.5 1.3 0.3 setosa42 4.5 2.3 1.3 0.3 setosa43 4.4 3.2 1.3 0.2 setosa44 5.0 3.5 1.6 0.6 setosa45 5.1 3.8 1.9 0.4 setosa46 4.8 3.0 1.4 0.3 setosa47 5.1 3.8 1.6 0.2 setosa48 4.6 3.2 1.4 0.2 setosa49 5.3 3.7 1.5 0.2 setosa50 5.0 3.3 1.4 0.2 setosa$versicolor Sepal.Length Sepal.Width Petal.Length Petal.Width Species51 7.0 3.2 4.7 1.4 versicolor52 6.4 3.2 4.5 1.5 versicolor53 6.9 3.1 4.9 1.5 versicolor54 5.5 2.3 4.0 1.3 versicolor55 6.5 2.8 4.6 1.5 versicolor56 5.7 2.8 4.5 1.3 versicolor57 6.3 3.3 4.7 1.6 versicolor58 4.9 2.4 3.3 1.0 versicolor59 6.6 2.9 4.6 1.3 versicolor60 5.2 2.7 3.9 1.4 versicolor61 5.0 2.0 3.5 1.0 versicolor62 5.9 3.0 4.2 1.5 versicolor63 6.0 2.2 4.0 1.0 versicolor64 6.1 2.9 4.7 1.4 versicolor65 5.6 2.9 3.6 1.3 versicolor66 6.7 3.1 4.4 1.4 versicolor67 5.6 3.0 4.5 1.5 versicolor68 5.8 2.7 4.1 1.0 versicolor69 6.2 2.2 4.5 1.5 versicolor70 5.6 2.5 3.9 1.1 versicolor71 5.9 3.2 4.8 1.8 versicolor72 6.1 2.8 4.0 1.3 versicolor73 6.3 2.5 4.9 1.5 versicolor74 6.1 2.8 4.7 1.2 versicolor75 6.4 2.9 4.3 1.3 versicolor76 6.6 3.0 4.4 1.4 versicolor77 6.8 2.8 4.8 1.4 versicolor78 6.7 3.0 5.0 1.7 versicolor79 6.0 2.9 4.5 1.5 versicolor80 5.7 2.6 3.5 1.0 versicolor81 5.5 2.4 3.8 1.1 versicolor82 5.5 2.4 3.7 1.0 versicolor83 5.8 2.7 3.9 1.2 versicolor84 6.0 2.7 5.1 1.6 versicolor85 5.4 3.0 4.5 1.5 versicolor86 6.0 3.4 4.5 1.6 versicolor87 6.7 3.1 4.7 1.5 versicolor88 6.3 2.3 4.4 1.3 versicolor89 5.6 3.0 4.1 1.3 versicolor90 5.5 2.5 4.0 1.3 versicolor91 5.5 2.6 4.4 1.2 versicolor92 6.1 3.0 4.6 1.4 versicolor93 5.8 2.6 4.0 1.2 versicolor94 5.0 2.3 3.3 1.0 versicolor95 5.6 2.7 4.2 1.3 versicolor96 5.7 3.0 4.2 1.2 versicolor97 5.7 2.9 4.2 1.3 versicolor98 6.2 2.9 4.3 1.3 versicolor99 5.1 2.5 3.0 1.1 versicolor100 5.7 2.8 4.1 1.3 versicolor$virginica Sepal.Length Sepal.Width Petal.Length Petal.Width Species101 6.3 3.3 6.0 2.5 virginica102 5.8 2.7 5.1 1.9 virginica103 7.1 3.0 5.9 2.1 virginica104 6.3 2.9 5.6 1.8 virginica105 6.5 3.0 5.8 2.2 virginica106 7.6 3.0 6.6 2.1 virginica107 4.9 2.5 4.5 1.7 virginica108 7.3 2.9 6.3 1.8 virginica109 6.7 2.5 5.8 1.8 virginica110 7.2 3.6 6.1 2.5 virginica111 6.5 3.2 5.1 2.0 virginica112 6.4 2.7 5.3 1.9 virginica113 6.8 3.0 5.5 2.1 virginica114 5.7 2.5 5.0 2.0 virginica115 5.8 2.8 5.1 2.4 virginica116 6.4 3.2 5.3 2.3 virginica117 6.5 3.0 5.5 1.8 virginica118 7.7 3.8 6.7 2.2 virginica119 7.7 2.6 6.9 2.3 virginica120 6.0 2.2 5.0 1.5 virginica121 6.9 3.2 5.7 2.3 virginica122 5.6 2.8 4.9 2.0 virginica123 7.7 2.8 6.7 2.0 virginica124 6.3 2.7 4.9 1.8 virginica125 6.7 3.3 5.7 2.1 virginica126 7.2 3.2 6.0 1.8 virginica127 6.2 2.8 4.8 1.8 virginica128 6.1 3.0 4.9 1.8 virginica129 6.4 2.8 5.6 2.1 virginica130 7.2 3.0 5.8 1.6 virginica131 7.4 2.8 6.1 1.9 virginica132 7.9 3.8 6.4 2.0 virginica133 6.4 2.8 5.6 2.2 virginica134 6.3 2.8 5.1 1.5 virginica135 6.1 2.6 5.6 1.4 virginica136 7.7 3.0 6.1 2.3 virginica137 6.3 3.4 5.6 2.4 virginica138 6.4 3.1 5.5 1.8 virginica139 6.0 3.0 4.8 1.8 virginica140 6.9 3.1 5.4 2.1 virginica141 6.7 3.1 5.6 2.4 virginica142 6.9 3.1 5.1 2.3 virginica143 5.8 2.7 5.1 1.9 virginica144 6.8 3.2 5.9 2.3 virginica145 6.7 3.3 5.7 2.5 virginica146 6.7 3.0 5.2 2.3 virginica147 6.3 2.5 5.0 1.9 virginica148 6.5 3.0 5.2 2.0 virginica149 6.2 3.4 5.4 2.3 virginica150 5.9 3.0 5.1 1.8 virginica
map()
(cont.)Fit a linear model between Petal.Width ~ Petal.Length
and extract the second coefficient.
library(magrittr)iris_species %>% map(~lm(Petal.Width ~ Petal.Length, data = .x)) %>% map(coef) %>% map_dbl(2)
setosa versicolor virginica 0.2012451 0.3310536 0.1602970
iris_species %>% map(~lm(Petal.Width ~ Petal.Length, data = .x)) %>% map(coef) %>% map_dbl(2)
setosa versicolor virginica 0.2012451 0.3310536 0.1602970
models <- lapply(iris_species, function(data) lm(Petal.Width ~ Petal.Length, data = data))vapply(models, function(x) coef(x)[[2]], double(1))
setosa versicolor virginica 0.2012451 0.3310536 0.1602970
Or use for loop
iris_species %>% map(~lm(Petal.Width ~ Petal.Length, data = .x)) %>% map(coef) %>% map_dbl(2)
setosa versicolor virginica 0.2012451 0.3310536 0.1602970
intercepts <- double(length(iris_species))for (i in seq_along(iris_species)) { model <- lm(Petal.Width ~ Petal.Length, data = iris_species[[i]]) intercepts[[i]] <- coef(model)[[2]]}intercepts
[1] 0.2012451 0.3310536 0.1602970
map
variants: modify
df <- data.frame( x = 1:3, y = 6:4)map(df, ~ .x * 10)
$x[1] 10 20 30$y[1] 60 50 40
# If you want to keep the output as a data frame, you can use modify()modify(df, ~ .x * 10)
x y1 10 602 20 503 30 40
modify
returns the same type of output as the input.
map_df
map_output <- map(mtcars, function(x) length(unique(x)))head(map_output, 3)
$mpg[1] 25$cyl[1] 3$disp[1] 27
map_df_output <- map_df(mtcars, function(x) length(unique(x)))head(map_df_output)
# A tibble: 1 x 11 mpg cyl disp hp drat wt qsec vs am gear carb <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>1 25 3 27 22 22 29 30 2 2 3 6
map
/map_df
/modify
set.seed(2020)x <- list(a=rnorm(5), b=rnorm(6))map(x, mean)
$a[1] -0.8692886$b[1] 0.4089487
map_df(x, mean)
# A tibble: 1 x 2 a b <dbl> <dbl>1 -0.869 0.409
modify(x, mean)
$a[1] -0.8692886$b[1] 0.4089487
Slides available at: hellor.netlify.app
All rights reserved by Thiyanga S. Talagala
Reference: Advanced R, Hadley Wickham
A functional is a function that takes a function as an input and returns a vector as output.
Hadley Wickham, Advanced R
statistic <- function(f){ data <- c(10, 20, 30, 40, 62, 63) f(data)}
statistic(mean)
[1] 37.5
statistic(sum)
[1] 225
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
s | Start & Stop the presentation timer |
t | Reset the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |