purrr

purrr ํŒจํ‚ค์ง€ ํ›‘์–ด๋ณด๊ธฐ

purrr๋Š” R์—์„œ ๊น”๋”ํ•˜๊ฒŒ ๋ฐ˜๋ณต ์ž‘์—… ์ฒ˜๋ฆฌํ•˜๋Š” ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค. Purrr ์„ ์ด์šฉํ•˜๋ฉด ๋ฐ˜๋ณต์ž‘์—…์„ Apply family ์— ๋น„ํ•ด ๋”์šฑ ์ง๊ด€์ ์ด๊ณ  ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. purrr๋Š” ๊ณ ์–‘์ด ์šธ์Œ์†Œ๋ฆฌ์™€ R์˜ ํ•ฉ์„ฑ์–ด๋กœ, ๋กœ๊ณ ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

1
library(tidyverse)

purrr logo

๋ชฉ์ฐจ

  1. map, map2
  2. pmap, invoke_map
  3. rerun
  4. every, some, none
  5. reduce, accumulate

map, map2

1
2
3
4
5
num <- c(1,2,4,5,7)
num2 <- c(3,5,6,8,9)

#list
map(num, function(x){x^2})
## [[1]]
## [1] 1
## 
## [[2]]
## [1] 4
## 
## [[3]]
## [1] 16
## 
## [[4]]
## [1] 25
## 
## [[5]]
## [1] 49
1
map2(num, num2, sum)
## [[1]]
## [1] 4
## 
## [[2]]
## [1] 7
## 
## [[3]]
## [1] 10
## 
## [[4]]
## [1] 13
## 
## [[5]]
## [1] 16
1
2
#numeric vector
map_dbl(num, function(x){x^2})
## [1]  1  4 16 25 49
1
map2_dbl(num, num2, sum)
## [1]  4  7 10 13 16

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
n_iris <- iris %>%
  group_by(Species) %>%
  nest()

mod_fun <- function(df){
  lm(Sepal.Length ~ ., data = df)
  }
  
m_iris <- n_iris %>%
  mutate(model = map(data, mod_fun))

b_fun <- function(mod){
  coefficients(mod)[[1]]
}

m_iris %>% transmute(Species, beta = map_dbl(model, b_fun))
## # A tibble: 3 x 2
## # Groups:   Species [3]
##   Species     beta
##   <fct>      <dbl>
## 1 setosa     2.35 
## 2 versicolor 1.90 
## 3 virginica  0.700

map


pmap, invoke_map

1
2
3
4
5
6
x <- list(3, 6, 9)
y <- list(10, 21, 30)
z <- list(100, 200, 300)

# pmap์€ 3๊ฐœ ์ด์ƒ์˜ ๋ฆฌ์ŠคํŠธ์ผ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
pmap(list(x, y, z), sum)
## [[1]]
## [1] 113
## 
## [[2]]
## [1] 227
## 
## [[3]]
## [1] 339
1
2
# invoke_map์€ ๊ฐ๊ฐ์˜ ๋ฆฌ์ŠคํŠธ์— ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์ ์šฉ์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ ํ™œ์šฉํ•œ๋‹ค.
invoke_map(list(runif, rnorm), list(list(n = 10), list(n = 5)))
## [[1]]
##  [1] 0.07250356 0.88643385 0.53457501 0.45493290 0.95970419 0.57638199
##  [7] 0.62800763 0.63266467 0.64451000 0.77471082
## 
## [[2]]
## [1]  0.1348207 -0.5144428 -0.8763132  0.8955774  0.3386345

rerun

rerun์€ ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌ์ŠคํŠธ ํ˜•์‹์œผ๋กœ ํ˜•์„ฑํ•˜๋Š” ๋ฐ์— ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ด๋‹ค.

1
2
3
4
5
# ์˜ˆ์‹œ
set.seed(2021)
a <- 10 %>% 
  rerun(rnorm(5))
a
## [[1]]
## [1] -0.1224600  0.5524566  0.3486495  0.3596322  0.8980537
## 
## [[2]]
## [1] -1.92256952  0.26174436  0.91556637  0.01377194  1.72996316
## 
## [[3]]
## [1] -1.0822049 -0.2728252  0.1819954  1.5085418  1.6044701
## 
## [[4]]
## [1] -1.841476  1.623310  0.131389  1.481122  1.513318
## 
## [[5]]
## [1] -0.9424433 -0.1856850 -1.1011246  1.2081153 -1.6249385
## 
## [[6]]
## [1]  0.10537833 -1.45544335 -0.35401614 -0.09370004  1.10066863
## 
## [[7]]
## [1] -1.9638251 -1.4479444  1.0194434 -1.4214171 -0.6045321
## 
## [[8]]
## [1] -1.58347390 -1.28593235 -1.45468488 -0.08707112  0.50473644
## 
## [[9]]
## [1]  0.11638871  1.76021373 -0.34511646  2.12000016 -0.03437749
## 
## [[10]]
## [1] -0.7921541  1.4755152 -0.7255572  0.3123790  0.6919641
1
2
3
4
5
6
7
# ์œ„ ํ•จ์ˆ˜๋Š” ์•„๋ž˜์˜ ํ•จ์ˆ˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์‚ฐ์ถœํ•จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
set.seed(2021)
b <- list()
for(i in 1:10){
  b[[i]] <- rnorm(5)
  print(b[i])
}
## [[1]]
## [1] -0.1224600  0.5524566  0.3486495  0.3596322  0.8980537
## 
## [[1]]
## [1] -1.92256952  0.26174436  0.91556637  0.01377194  1.72996316
## 
## [[1]]
## [1] -1.0822049 -0.2728252  0.1819954  1.5085418  1.6044701
## 
## [[1]]
## [1] -1.841476  1.623310  0.131389  1.481122  1.513318
## 
## [[1]]
## [1] -0.9424433 -0.1856850 -1.1011246  1.2081153 -1.6249385
## 
## [[1]]
## [1]  0.10537833 -1.45544335 -0.35401614 -0.09370004  1.10066863
## 
## [[1]]
## [1] -1.9638251 -1.4479444  1.0194434 -1.4214171 -0.6045321
## 
## [[1]]
## [1] -1.58347390 -1.28593235 -1.45468488 -0.08707112  0.50473644
## 
## [[1]]
## [1]  0.11638871  1.76021373 -0.34511646  2.12000016 -0.03437749
## 
## [[1]]
## [1] -0.7921541  1.4755152 -0.7255572  0.3123790  0.6919641
1
2
3
for(i in 1:10){
  print(a[[i]] == b[[i]])
}
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
## [1] TRUE TRUE TRUE TRUE TRUE
1
2
# ์ฐธ๊ณ ๋กœ, base์— ์žˆ๋Š” replicate์™€ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ์ง€ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์ž!
replicate(10, rnorm(5))
##             [,1]       [,2]        [,3]       [,4]        [,5]       [,6]
## [1,] -0.50029080  0.1037663  0.01604353 -0.9836134 -0.34823176 -0.2369450
## [2,] -2.25586935  0.4272891 -0.18536431  0.5650808 -0.04298997 -0.9991415
## [3,]  0.04374133 -0.1704815  0.39193326  1.6167519 -1.39755396 -1.3925426
## [4,] -0.36881809 -1.5491403 -0.75671092 -0.2519641  1.49021633  0.9820053
## [5,] -0.96022240 -1.5055999  0.23141761 -1.0558786 -1.03938712  0.3609409
##            [,7]       [,8]        [,9]      [,10]
## [1,] -0.3375092 -1.2400271  0.81061837 -0.1220018
## [2,] -0.6433876  0.5339593 -0.29366457 -0.6467737
## [3,] -2.1668853 -1.5882648 -0.05345832 -0.8678583
## [4,]  0.6332890 -0.9909645  0.73518450 -0.5087003
## [5,] -0.1449141  0.4832608  0.01498499 -2.0775844
1
typeof(a)
## [1] "list"
1
typeof(replicate(10, rnorm(5)))
## [1] "double"

every, some, none

๋ฆฌ์ŠคํŠธํ˜•์‹์„ summariseํ•˜๋Š” ๋ฐ์— ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ด๋‹ค.

1
2
y <- list(0:10, 5.5)
y
## [[1]]
##  [1]  0  1  2  3  4  5  6  7  8  9 10
## 
## [[2]]
## [1] 5.5
1
y %>% every(is.numeric)
## [1] TRUE
1
y %>% every(is.integer)
## [1] FALSE
1
y %>% some(is.integer)
## [1] TRUE
1
y %>% none(is.character)
## [1] TRUE

reduce, accumulate

ํ•จ์ˆ˜๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ(recursively) ์ ์šฉ์‹œํ‚ค๋Š” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์ด๋‹ค.

1
2
#1. reduce:
reduce(1:10, sum)
## [1] 55
1
2
#2. accumulate
accumulate(1:10, sum)
##  [1]  1  3  6 10 15 21 28 36 45 55
1
2
3
#reduce ์‘์šฉ ๋ฒ„์ „
paste2 <- function(x, y, sep = ".") paste(x, y, sep = sep)
letters[1:4] %>% reduce(paste2)
## [1] "a.b.c.d"