Iteration with map
https://onesixx.com/13-iterating-with-purrr/
http://r4ds.had.co.nz/iteration.html#the-map-functions
https://www.rstudio.com/resources/videos/happy-r-users-purrr-tutorial/
https://github.com/rstudio/rstudio-conf/tree/master/2017/Happy_R_Users_Purrr-Charlotte_Wickham
http://purrr.tidyverse.org/reference/map.html
http://statkclee.github.io/parallel-r/ds-fp-purrr.html
http://r4ds.had.co.nz/iteration.html#the-map-functions
https://stackoverflow.com/questions/38403111/ways-to-add-multiple-columns-to-data-frame-using-plyr-dplyr-purrr
https://www.r-bloggers.com/rebuilding-map-example-with-apply-functions/
purrr에서 map()만 사용한다면 큰 의미가 없다.
https://jtr13.github.io/spring19/ss5593&fq2150.html
pacman::p_load("repurrrsive") # sw_films 각 영화 7개의 list, 각 영화는 14개의 list로 이루어짐. sw_films %>% lapply(function(x){x[["director"]]}) sw_films %>% map(~ .x[["director"]]) sw_films %>% map(~ .[["director"]])
purrr의 장점
- 일관된 문법 , 일관된 return type
(sapply() & lapply()는 return이 상황에 따라 다르다.) - Pipe사용가능
- 함수의 인수(mean()함수의 trim이나 na.rm )을 바로 붙여 사용할수 있다.
- map functions 은 name을 유지한다.
- 간결한 shortcuts .
.
은 대명사 (for루프에서 i가 현재 index를 대신하듯이, . 은 현재 list요소를 대신한다)
function(x){ x+1 } 은~ .+1
즉 X %>% lapply(function(x) x+1) 은 X %>% map(~{.+1})
lapply(list, function(x) x[[2]]) map(list, function(x) x[[2]]) map(list, 2)
- 가져올 요소의 위치(Position)을 Integer를 사용하여 대신할수 있다.
apply와 비교
반복문
Map() 의 종류
map_returnType
map function | makes a | |
---|---|---|
map() | list | lapply(), sapply() |
map_lgl() | logical vector | |
map_int() | integer vector | |
map_dbl() | double vector | |
map_chr() | character vector |
각 map 함수는 vector를 input으로 받아서, 각 vector에 함수를 적용하고,
같은이름과 length의 새로운 vector를 output으로 return한다.
(map 함수의 접미사는 vector 유형을 결정한다.)
for루프의 속도는 많이 향상되었기 때문에, Map 함수는 속도보다는 코드의 간결/정확함을 위해 사용한다고 생각하면 된다.
map_if(), map_at()
argument가 여러개일때 Mapping
map2(.x, .y, .f, …)

pmap(.l, .f, …)


example.
function이 여러개일때 Mapping
invoke_map() 함수
f <- c("runif", "rnorm", "rpois") param <- list( list(min = -1, max = 1), list(sd = 5), list(lambda = 10) ) invoke_map(f, param, n = 5) %>% str()

sim <- tribble( ~f, ~params, "runif", list(min = -1, max = 1), "rnorm", list(sd = 5), "rpois", list(lambda = 10) ) sim %>% mutate(sim = invoke_map(f, params, n = 10))
SOLVE ITERATION PROBLEMS
FOR EACH __DO __
You are already solving them:
copy & paste, for loops, (l/s)apply()
I’ll show you an alternative purrr::map() & friends
library(purrr) library(tidyverse)
load("~/Dropbox/Rhome/purr/data/swapi.rda")
map( .x, .f, …)
for each element of .x do .f
Other types of output : map_lgl( .x, .f, …)
- map_lgl() logical vector
- map_int() integer vector
- map_dbl() double vector
- map_chr() character vecto
Other ways of specifying .f : map( .x, length, …)
Other iteration functions : map2( .x, .y, .f, …)
map() 항상 list를 return한다.
identical
map(.x, .f = some_function, …)
map(.x, ~ some_function(.x, …))
map(people, ~ .x[[“hair_color”]])
map(people, .f = “hair_color”)
map(people, “hair_color”)
Dealing with failure
http://r4ds.had.co.nz/iteration.html#dealing-with-failure
여러 operation을 반복하기 위해 map 함수를 사용하다보면 그만큼 operation이 오류를 일으킬 확률이 높아진다.
하나때문에 모든 operation이 안돌아가고, 그게 어떤건지 찾는건 좀 짜증나는 일이다.
safely(.f, otherwise = NULL, quiet = TRUE)
quietly(.f)
possibly(.f, otherwise, quiet = TRUE)
safely()
뭔가 잘못되더라도, 함수가 실행되는 것을 멈추지 한는다.
Base R의 try와 비슷한 safely 는 함수를 감싸서 결과를 두가지로 알려준다.
-
result
is the original result. If there was an error, this will beNULL
. -
error
is an error object. If the operation was successful, this will beNULL
.
log(10) # 2.302585 safe_log <- safely(log)
- 정상적인 경우
str(safe_log(10)) c(10) %>% map(safely(log)) %>% str()
List of 2 $ result: num 2.3 $ error : NULL
- 에러상황 : 문자에 log를 취하려고 함
str(safe_log("a")) c("a") %>% map(safely(log)) %>% str()
List of 2 $ result: NULL $ error :List of 2 ..$ message: chr "non-numeric argument to mathematical function" ..$ call : language .f(...) ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
ex2> https://www.r-bloggers.com/lesser-known-purrr-tricks/
safely()
는 아래 possibly()
와 비슷하지만 list의 list를 return한다. (result리스트와 error 메세지)
numbers_with_error <- list(1, 2, 3, "spam", 4)
safe_sqrt <- safely(sqrt, otherwise = NA_real_) map(numbers_with_error, safe_sqrt)
possible_sqrt <- possibly(sqrt, otherwise = NA_real_) map(numbers_with_error, possible_sqrt)
possibly()
에러상황: 정의된 값으로 대체한다.
x <- list(1, 10, "a") x %>% map_dbl(possibly(log, NA_real_))
[1] 0.00 2.30 NA
quietly()
safely()와 비슷하지만, 에러를 잡는대신 printed output, messages, warnings을 잡는다.
x <- list(1, -1) x %>% map(quietly(log)) %>% str()