Apply functions with purrr:: Cheatsheet Apply Functions Map functions apply a function iteratively to each element of a list or vector. map( map2 pmap( fun, fun,. fun( fund fun(l fun( fund fund invoke_map( fun(| fun,..>fun(| fun(| fun fun rnapi.x, .f,...) Apply a function to each element of a list or vector. map(x, is.logical) map2(.x, ,y, .f,...) Apply a function to pairs of elements from two lists, vectors. map2(x, y, sum) pmapLl, .f,...) Apply a function to groups of elements from list of lists, vectors. pmap(list(x, y, z), sum, na.rm = TRUE) invoke_map(.f, .x = list(NULL)......env=NULL) Run each function in a list. Also invoke. / <- listfvar, sd); invoke_map(l, x = 1:9) Imapi.x, .f,...) Apply function to each list-element of a list orvector. imapi.x, .f,...) Apply .f to each element of a list or vector and its index. OUTPUT map(),map2(),pmap(), imap and invoke_map each return a list. Use a suffixed version to return the results as a specific type of flat vector, e.g. map2_chr, pmap_lgl, etc. Use walk, walk2, and pwalk to trigger side effects. Each return its input invisibly. function returns map list map_chr character vector map_dbl double (numeric) vector map_dfc data frame (column bind) map_dfr data frame (row bind) map_int integer vector map_lgl logical vector walk triggers side effects, returns the input invisibly SHORTCUTS-within a purrr function: "name" becomes function(x) x$name. e.g. map(l, "a") extracts $a from each element of/ -. becomes function(x) x. e.g. map(l, ~2+.) becomes map(l, function(x) 2 + x) @Stud 10 - .x .y becomes function(.x, .y) .x .y. e.g. map2(l, p, ~.x+.y) becomes map2(l, p, function(l, p) / + p) - ..1 ..2 etc becomes functional, ..2, etc) ..1 ..2 etc e.g.pmap(list(a, b, c), ~..3 + ..l-..2) becomes pmap(list(a, b, c), function(a, b,c)c + a-b) Work with Lists FILTER LISTS a ■ pluck(.x,...,.default=NULL) Select an element by name or index, pluck(x,"b") ,or its attribute with attr_getter. pluck(x,"b ",attr_getter("n")) keepf.x, .p,...) Select elements that pass a logical test. keep(x, is.na) discard(.x, .p,...) Select elements that do not pass a logical test. discard(x, is.na) compact!.x, .p = identity) Drop empty elements. compact(x) head_while(.x, .p,...) Return head elements until one does not pass. Also tail_while. head_while(x, is.character) RESHAPE LISTS x y x y (a : a (!_) b ■ ■ (m~) c 1 flatten).x) Remove a level of indexes from a list. Also flatten_chr, flatten_dbl, flatten_dfc, flatten_dfr, flatten_int, flatten_lgl. flatten(x) transpose!.I, .names = NULL) Transposes the index order in a multi-level list. transpose(x) Reduce Lists a b (■,1 ' -S fundi SUMMARISE LISTS • false every(.x,.p,...) Doall element pass a test? every(x, is.character) ,TRUE somef.x, .p,...) Do some elements pass a test? some(x, is.character) . TRUE has_element(.x, .y) Does a list contain an element? has_element(x, "foo") xy z la ) ■■ ) ) detectf.x, .f,.right=FALSE, .p) Find first element to pass. detect(x, is.character) detect_index(.x, .f,.right = FALSE, .p) Find index of first element to pass. detect_index(x, is.character) depth(x) Return depth (number of levels of indexes), depth(x) JOIN (TO) LISTS appendix, values, after = length(x)) Add to end of list. appendix, list(d = 1)) prependix, values, before = 1) Add to start of list. prepend(x, list(d = 1)) splicef...) Combine objects into a list, storing S3 objects as sub-lists. splice(x, y "foo") TRANSFORM LISTS a ■ -»• ■ ■ ■ ■ d ■ _ aB ■ ■ ■ ■ d ■. - _ _ ■ a ■ ■ ■ ■ ■ - modifyf.x, .f,...) Apply function to each element. Also map, map_chr, map_dbl, map_dfc, map_dfr, map_int, map_lgl. modify(x, ~.+ 2) modify_at(.x, .at, .f,...) Apply function to elements by name or index. Also map_at. modify_at(x, "b", ~.+ 2) modify_if(.x, .p, .f,...) Apply function to elements that pass a test. Also map_if. modify_if(x, is.numeric, ~. +2) modify_depth(.x,.depth,.f,...) Apply function to each element at a given level of a list. modify_depth(x, 1, ~.+2) WORK WITH LISTS CD cm; array_tree(array, margin = NULL) Turn array into list. Also array_branch. array_tree(x, margin =3) cross2(.x, .y, .filter = NULL) All combinations of .x and .y. Also cross, cross3, cross_df. cross2(l:3,4:6) set_names(x, nm =x) Set the names of a vector/list directly or with a function. set_names(x, c("p", "q" "r")) set_names(x, tolower) Modify function behavior func + (| ^ j a)-func("-" func func + ľa b c dl—. [■ ■ ■ "J func( func(l funcfl T" d, reducei.x, .f,.init) Apply function recursively to each element of a list or vector. Also reduce_right, reduce2, reduce2_right. reduce(x, sum) accumulatel.x, .f,.init) Reduce, but also return intermediate results. Also accumulate_right. accumulate^, sum) compose!) Compose multiple functions. lift() Change the type of input a function takes. Also lift_dl, lift_dv, liftjd, lift_lv, lift_vd, lift_vl. rerun() Rerun expression n times. negate() Negate a predicate function (a pipe friendly!) partial)) Partially apply a function, filling in some args. safelyl) Modify func to return list of results and errors. quietlyi) Modify function to return list of results, output, messages, warnings. possibly!) Modify function to return default value whenever an error occurs (instead of error). RStudio® is a trademark of RStudio, Inc. • CC BY RStudio • info@rstudio.com • 844-448-1212 • rstudio.com • Learn more at purrr.tidvverse.ore ■ purrr 0.2.3« Updated: 2017-09 Nested Data A nested data frame stores individual tables within the cells of a larger, organizing table. nested data frame "cell" contents 3.5 1.4 0.2 4.6 5.0 0.2 n_i ris$data[[l]] setosa versicolor virginica Use a nested data frame to: • preserve relationships between observations and subsets of data • manipulate many sub-tables kl=UHW 7.0 3.2 4.7 1.4 6.4 3.2 4.5 1.5 6.9 3.1 4.9 1.5 5.5 2.3 4.0 1.3 6.5 2.8 4.6 1.5 n_i ris$data[[2] 6.5 3.0 5.8 2.2 n_i ris$data[[3]] at once with the purrr functions map(), map2(), or pmap(). Use a two step process to create a nested data frame: 1. Group the data frame into groups with dplyr::group_ 2. Use nest() to create a nested data frame with one row per group by() setosa setosa setosa setosa setosa versi versi versi versi versi virgini virgini virgini virgini virgini 5.1 3.51.40.2 4.9 3.01.4 0.2 4.7 3.21.3 0.2 4.6 3.1 1.5 0.2 5.0 3.61.40.2 7.0 3.24.7 1.4 6.4 3.24.5 1.5 a 6.9 3.1 4.9 1.5 " 5.5 2.34.0 1.3 6.5 2.84.6 1.5 6.3 3.3 6.0 2.5 5.8 2.75.1 1.9 7.1 3.0 5.9 2.1 6.3 2.95.6 1.8 6.5 3.0 5.8 2.2 versi versi versi versi versi virgini virgini virgini virgini virgini 5.1 3.5 1.40.2 ■ ■■■ ■ ■■■ 4.6 3.1 1.5 0.2 5.0 3.6 1.4 0.2 7.0 3.2 4.7 1.4 6.4 3.2 4.5 1.5 b 6.9 3.1 4.9 1.5 B 5.5 2.3 4.0 1.3 6.5 2.8 4.6 1.5 6.3 3.3 6.0 2.5 ■ ■■■ ■ ■■■ ■ ■■■ 6.5 3.0 5.8 2.2 E33 setos <^b^50^? versi virgini / 5.1 3.51.40.2 4.9 3.01.4 0.2 4.7 3.21.3 0.2 ■ ■■■ 5.0 3.61.4 0.2 7.0 3.2 4.7 1.4 6.4 3.2 4.5 1.5 6.9 3.1 4.9 1.5 5.5 2.3 4.0 1.3 6.5 2.8 4.6 1.5 n_iris <- iris %>% group_by(Species) %>% nestQ tidyr::nest(data..key = data) For grouped data, moves groups into cells as data frames. ■■■■ ■■■■ ■■■■ ■■■■ ■■■■ setos versi virgini Unnest a nested data frame with unnest(): n_iris %>% unnestC tidyr::unnest(data,.drop = NA, .id=NULL, .sep=NULI_) Unnests a nested data frame. @Stud IO setosa 5.1 setosa 4.9 setosa 4.7 setosa 4.6 versi 7.0 versi 6.4 versi 6.9 versi 5.5 virgini 6.3 virgini 5.8 virgini 7.1 virgini 6.3 3.5 1.4 0.2 3.0 1.4 0.2 3.2 1.3 0.2 3.1 1.5 0.2 3.2 4.7 1.4 3.2 4.5 1.5 3.1 4.9 1.5 2.3 4.0 1.3 3.3 6.0 2.5 2.7 5.1 1.9 3.0 5.9 2.1 2.9 5.6 1.8 List Column Workflow Make a list column versi versi versi versi virgini virgini virgini virgini I EHE! El 1 3.51.4 0.2 3 3.01.4 0.2 7 3.21.3 0.2 3 3.1 1.5 0.2 D 3.2 4.7 1.4 i 3.24.5 1.5 -3 3.1 4.9 1.5 5 2.3 4.0 1.3 3 3.3 6.0 2.5 3 2.75.1 1.9 1 3.0 5.9 2.1 3 2.9 5.6 1.8 5.1 3.5 1.40.2 ■ ■■■ ■ ■■■ 4.6 3.1 1.50.2 7.0 3.2 4.71.4 6.4 3.2 4.51.5 6.9 3.1 4.91.5 5.5 2.3 4.01.3 Nested data frames use a list column, a list that is stored as a column vector of a data frame. A typical workflow for list columns: Work with list columns Call: lm(S.l~.,df) Coefs: (Int) S.W p.l p.W E23 setosa versi virgini 2.3 0.6 0.2 0.2 lm(S.l~.,clf) Coefs: (Int) S.W p.l p.W 1.8 0.3 0.9 -0.6 versi virgini | 6.3 3.3 6.0 2.5 ■ ■■■ 7.1 3.0 5.92.1 6.3 2.9 5.61.8 Call: -,df) n_iris <- iris %>% group_by(Species) %>°, nestQ lm(S.l~ Coefs: (Int) S.W p.l p.W 0.6 0.3 0.9 -0.1 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)[[l]] m_iris %>% transmute(Species, beta = map_dbl(model, b_fun)) 1. MAKE A LIST COLUMN - You can create list columns with functions in the tibble and dplyr packages, as well as tidyr's nest() tibble::tribble(.) Makes list column when needed thbble( -max, ~seq, 3, 1:3, 4, 1:4, 5, 1:5) 3 4 5 tibble::tibble( ) Saves list input as list columns tibble(max = c(3,4,5), seq = list(l:3,1:4,1:5)) tibble::enframe(x, name="name", value-'value") Converts multi-level list to tibble with list cols enframe(list('3'=l:3, '4-1:4, '5-1:5), 'max', 'seq') dplyr::mutate(.data,...) Also transmute)) Returns list col when result returns list, mtcars %>% mutate(seq = map(cyl, seq)) dplyr::summarise(.data,...) Returns list col when result is wrapped with listQ mtcars %>% group_by(cyl) %>% summariseiq = list(quantile(mpg))) map( map2( pmap(list( [50x4]> [50x4]> fun,. 2. WORK WITH LIST COLUMNS - Use the purrr functions map(), map2(), and pmap() to apply a function that returns a result e to the cells of a list column. walk(), walk2(), and pwalk() work the same way, but return a sid purrr::map(.x, .f,...) Apply .f element-wise to .x as .f(.x) n_iris %>% mutate(n = map(data, dim)) purrr::map2(.x, .y, .f,...) Apply .f element-wise to .x and .y as .f(.x, .y) m_iris %>% mutate(n = map2(data, model, list)) purrr::pmap(.l; .f,...) Apply .f element-wise to vectors saved in .1 m_iris %>% mutate(n = pmap(list(data, model, data), list)) ement-\ e effect. [50x4]> ' [50x41> [50x4]> [50x4]> [50x4]> ' > fun,. BIC JUn( » ' fünf , fun( , funt nibble [50x4]> j > ■ fünf , , funí j coef , , AIC fünf BIC result 1 " result 2 result 2 result 3 result 1 result 2 result 3 3. SIMPLIFY THE LIST COLUMN (into a regular column) purrr::map_lgl(.x, f,...) Apply .f element-wise to .x, return a logical vector n_iris %>% transmuted! = map_lgl(data, is.matrix)) purrr::map_int(.x; .f,...) Apply .f element-wise to .x, return an integervector n_iris %>% transmutein = map_int(data, nrow)) Use the purrr functions map_lgl(), map_int(), map_dbl(), map_chr(), as well as tidyr's unnestQ to reduce a list column into a regular column. purrr::map_dbl(.x, f,...) Apply .f element-wise to .x, return a double vector n_iris %>% transmutein = map_dbl(data, nrow)) purrr::map_chr(.x, .f,...) Apply .f element-wise to .x, return a character vector n_iris %>% transmutein = map_chr(data, nrow)) RStudio® is a trademark of RStudio, Inc. • CC BY RStudio • info@rstudio.com • 844-448-1212 • rstudio.com • Learn more at purrr.tidvverse.ore ■ purrr 0.2.3« Updated: 2017-09