Iteration with map

Published by onesixx on

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의 장점

R
  • 일관된 문법 , 일관된 return type
    (sapply() & lapply()는 return이 상황에 따라 다르다.)
  • Pipe사용가능
  • 함수의 인수(mean()함수의  trim이나 na.rm )을 바로 붙여 사용할수 있다. 
R
  • map functions 은  name을 유지한다.
R
  • 간결한 shortcuts .
     . 은 대명사  (for루프에서 i가 현재 index를 대신하듯이,  . 은 현재 list요소를 대신한다)
R
  • 가져올 요소의 위치(Position)을 Integer를 사용하여 대신할수 있다.
R

apply와 비교

R

Map() 의 종류

map_returnType

map functionmakes 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()

R

argument가 여러개일때 Mapping

map2(.x, .y, .f, …)

R

pmap(.l, .f, …)

R
R

pmap(.l, .f, …)

set.seed(666); options(digits=2)

mu    <- list(5, 10, -3)
sigma <- list(1,  5, 10)
mu %>% map(rnorm, n = 5) %>% str()

seq_along(mu) %>% map(~rnorm(5, mu[[.]], sigma[[.]])) %>% str()
map2(mu, sigma, rnorm, n = 5) %>% str()

pmap => map3(), map4(),map5()………

n <- list(1, 3, 5)

args1 <- list(n, mu, sigma) 
args1 %>% pmap(rnorm) %>% str()
args2 <- list(mean = mu, sd = sigma, n = n)
args2 %>% pmap(rnorm) %>% str()
params <- tribble( 
    ~mean, ~sd, ~n, 
        5,   1,  1, 
       10,   5,  3,
       -3,  10,  5)

params %>% pmap(rnorm)

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 be NULL.
  • error is an error object.          If the operation was successful, this will be NULL.
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()
Categories: Tidyverse

onesixx

Blog Owner

Leave a Reply

Your email address will not be published.