### Install purrr Package in R Source: https://github.com/tidyverse/purrr/blob/main/README.md Demonstrates how to install the purrr package in R. It shows installation of the entire tidyverse, just purrr, and the development version from GitHub using pak. ```R install.packages("tidyverse") install.packages("purrr") # Or the the development version from GitHub: # install.packages("pak") pak::pak("tidyverse/purrr") ``` -------------------------------- ### pmap_vec: Verify type conversion Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/pmap.md Shows `pmap_vec`'s type conversion capabilities and limitations. This example specifically tests the conversion of a double to a character type, which results in an error. ```r pmap_vec(list(1), ~1, .ptype = character()) ``` -------------------------------- ### Replacing invoke_map() with map() and exec() in R Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Illustrates the replacement of `invoke_map()` with a combination of `map()` and `exec()`. This approach is considered more understandable for applying functions to arguments. The examples show how to handle single and multiple argument lists. ```r # Before: invoke_map(fns, list(args)) invoke_map(fns, list(args1, args2)) # After map(fns, exec, !!!args) map2(fns, list(args1, args2), function(fn, args) exec(fn, !!!args)) ``` -------------------------------- ### pmap: Input recycling behavior Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/pmap.md Demonstrates how `pmap` handles input recycling when combining lists of different lengths. It shows that inputs must be recyclable to a common length, and errors occur if they cannot be. ```r pmap(list(1:2, 1:3), `+`) pmap(list(1:2, integer()), `+`) ``` -------------------------------- ### Parallel Map Operations with in_parallel() in R Source: https://context7.com/tidyverse/purrr/llms.txt Explains how to perform parallel map operations using `in_parallel()` from the purrr package, which integrates with the `mirai` package. It covers setting up daemons, defining functions for parallel execution, using package functions with explicit namespacing, passing local dependencies, and enabling progress bars. Note: The code examples for `mirai::daemons()` and the parallel map operations are commented out as they require a specific setup and execution environment. ```r library(purrr) # Set up parallel daemons (run once per session) # mirai::daemons(4) # Use 4 parallel processes # Create a self-contained function for parallel execution # Functions must be: # 1. Freshly defined (anonymous function) # 2. Use explicit :: namespacing for package functions # 3. Declare all dependencies via ... # Basic parallel map # mtcars |> map_dbl(in_parallel(\(x) mean(x))) # With package functions - use explicit namespacing # 1:10 |> map(in_parallel(\(x) vctrs::vec_init(integer(), x))) # With local dependencies - pass via ... slow_lm <- function(formula, data) { Sys.sleep(0.5) lm(formula, data) } # mtcars |> # split(mtcars$cyl) | # map(in_parallel( # function(df) slow_lm(mpg ~ disp, data = df), # slow_lm = slow_lm # Pass local function as dependency # )) # With progress bars # mtcars |> map_dbl(in_parallel(\(x) mean(x)), .progress = TRUE) # Tear down daemons when done # mirai::daemons(0) ``` -------------------------------- ### pmap: Input validation for lists and vectors Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/pmap.md Illustrates the input requirements for the `pmap` function. It shows that the primary input `.l` must be a list, and its elements must be vectors, not environments. ```r pmap(environment(), identity) pmap(list(environment()), identity) ``` -------------------------------- ### Deprecated rdunif Function Example (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-utils.md Demonstrates the usage of the deprecated rdunif function from the purrr package. This function is no longer recommended for use as of purrr version 1.0.0. ```r . <- rdunif(10, 1) ``` -------------------------------- ### Coerce to Expression Vectors in Purrr Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/coerce.md Demonstrates the `coerce()` function's limitation when attempting to coerce a list to an expression vector. The example shows that this specific coercion is not supported and leads to an error. ```R coerce(list(1), "expression") # Error: ! Can't coerce from a list to expression. ``` -------------------------------- ### Reduce with Empty List (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/reduce.md Demonstrates that `reduce()` fails when called with an empty list and no initial value (`.init`). It requires `.init` to be supplied in such cases to provide a starting point for the reduction. ```r reduce(list()) ``` -------------------------------- ### Coerce to Double Vectors in Purrr Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/coerce.md Shows the `coerce_dbl()` function's behavior when coercing to double vectors. The example indicates that coercing a string representation of a number to a double is not directly supported and results in an error. ```R coerce_dbl("1.5") # Error: ! Can't coerce from a string to a double. ``` -------------------------------- ### Deprecated rbernoulli Function Example (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-utils.md Shows an example of the deprecated rbernoulli function from the purrr package. Users should be aware that this function has been deprecated since purrr 1.0.0. ```r . <- rbernoulli(10) ``` -------------------------------- ### pmap_int: Verify integer coercion and length Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/pmap.md Demonstrates `pmap_int`'s behavior when attempting to coerce non-integer types or incorrect lengths. It highlights that the function expects integer results of length 1. ```r pmap_int(list(1), ~"x") pmap_int(list(1), ~ 1:2) ``` -------------------------------- ### Validate modify_tree input: is_node returns a single TRUE or FALSE Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/modify-tree.md This example shows the correct usage of `modify_tree` where the `is_node` argument is a function that returns a single logical value (TRUE or FALSE). It highlights the expected input for this parameter. ```r modify_tree(list(), is_node = ~1) ``` -------------------------------- ### Purrr map: Input must be a vector Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/map.md Demonstrates that the `map()` function in purrr requires its first argument to be a vector. It shows errors when an environment or a symbol is provided instead. ```R map(environment(), identity) # Condition # Error in `map()`: # ! `.x` must be a vector, not an environment. ``` ```R map(quote(a), identity) # Condition # Error in `map()`: # ! `.x` must be a vector, not a symbol. ``` -------------------------------- ### Reduce2 with Unequal Length Vectors (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/reduce.md Shows that `reduce2()` requires input vectors to have compatible lengths. This example fails because the second input vector has a length of 1, while the function expects a length of 2. ```r reduce2(1:3, 1, `+`) ``` -------------------------------- ### Validate lmap .else argument type in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/lmap.md Illustrates `lmap`'s validation of the `.else` argument, ensuring it is a function. Providing an environment instead of a function triggers an error. ```r library(purrr) lmap(list(1), ~1, .else = environment()) # Expected Error: Error in `lmap()`: # ! Can't convert `.else`, an environment, to a function. ``` -------------------------------- ### Pre-fill Function Arguments with partial() in R Source: https://context7.com/tidyverse/purrr/llms.txt partial() creates a new function where some arguments of an original function are already set. This is useful for creating specialized versions of existing functions without needing to define a new function explicitly. The examples show creating a mean function that always removes NAs and a discard function that always removes NULLs. ```r library(purrr) # Create specialized function mean_rm_na <- partial(mean, na.rm = TRUE) mean_rm_na(c(1, 2, NA, 4)) #> [1] 2.333333 # Partial with discard compact_nulls <- partial(discard, .p = is.null) list(1, NULL, 2, NULL, 3) |> compact_nulls() #> [[1]] #> [1] 1 #> ... #> [[2]] #> [1] 2 #> ... #> [[3]] #> [1] 3 ``` -------------------------------- ### update_list() Deprecation Warning Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-modify.md Shows the deprecation warning issued when using the `update_list()` function. This function has been deprecated in purrr version 1.0.0 and users should migrate to alternative methods. ```r . <- update_list(list()) ``` -------------------------------- ### rdunif Error: Non-unit Length 'a' Parameter (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-utils.md Demonstrates an error when the 'a' parameter for rdunif is a vector with more than one element. The 'a' parameter must be a single numeric value. ```r rdunif(1000, 1, c(0.5, 0.2)) ``` -------------------------------- ### Coerce to Logical Vectors in Purrr Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/coerce.md Demonstrates the `coerce_lgl()` function's behavior when attempting to coerce different data types to logical vectors. It shows that direct coercion from integer, number, and string types to logical is not supported, resulting in errors. ```R coerce_lgl(2L) # Error: ! Can't coerce from an integer to a logical. coerce_lgl(1.5) # Error: ! Can't coerce from a number to a logical. coerce_lgl("true") # Error: ! Can't coerce from a string to a logical. ``` -------------------------------- ### Apply Function to Data Frame Splits using purrr in R Source: https://github.com/tidyverse/purrr/blob/main/README.md Example of using purrr's map functions to split a data frame, fit a linear model to each subset, compute the summary, and extract the R-squared value. This showcases purrr's functional programming capabilities and its compatibility with the R pipe. ```R library(purrr) mtcars |> split(mtcars$cyl) |> # from base R map(\(df) lm(mpg ~ wt, data = df)) |> map(summary) |> map_dbl("r.squared") ``` -------------------------------- ### Purrr map_int: Informing about problem location and output constraints Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/map.md Illustrates how `map_int()` provides specific information about the index where an error occurred and checks for output length and type compatibility. It shows errors when the output is not length 1 or cannot be coerced to an integer. ```R map_int(1:3, ~ fail_at_3(.x, 2:1)) # Condition # Error in `map_int()`: # i In index: 3. # Caused by error: # ! Result must be length 1, not 2. ``` ```R map_int(1:3, ~ fail_at_3(.x, "x")) # Condition # Error in `map_int()`: # i In index: 3. # Caused by error: # ! Can't coerce from a string to an integer. ``` ```R map(1:3, ~ fail_at_3(.x, stop("Doesn't work"))) # Condition # Error in `map()`: # i In index: 3. # Caused by error in `fail_at_3()`: # ! Doesn't work ``` -------------------------------- ### purrr API Changes: compose() and pmap() Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Documents changes in purrr's compose() function regarding parameter handling and print methods, and a fix for pmap() crashing with empty lists on Win32. ```r library(purrr) # compose() now uses parameters of the first function add_one <- function(x) x + 1 multiply_by_two <- function(x) x * 2 composed <- compose(add_one, multiply_by_two) print(formalArgs(composed)) # Output: "x" # pmap() fix for empty lists on Win32 (example assumes Win32 environment for testing) # This is a fix, so direct code example might not show difference without specific conditions. # If you encounter a crash with pmap() and empty lists on Win32, this update should resolve it. # Example of pmap usage: # data <- list(a = 1:3, b = 4:6) # pmap(data, ~ list(..1, ..2)) ``` -------------------------------- ### Reducing with 3-Argument Functions using reduce2() Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md The `reduce2()` and `reduce2_right()` functions enable reduction operations using functions that take three arguments. The first argument is the accumulated value, the second is from `.x`, and the third is from `.y`. This extends the capabilities of `purrr::reduce()`. They take a list, an initial value, and a function as input. ```R library(purrr) # Example: Using reduce2 to combine elements with an index my_vec <- c("a", "b", "c") reduce2(my_vec, "start", ~ paste0(.x, ".", .y, ".", .z), .y = 1:3) # Expected output: "start.a.1.b.2.c.3" # Example: Using reduce2_right reduce2_right(my_vec, "start", ~ paste0(.x, ".", .y, ".", .z), .y = 1:3) # Expected output: "start.c.3.b.2.a.1" ``` -------------------------------- ### List and Sequence Generation with list_along() and rep_along() in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Generalize the concept of `seq_along()` for creating lists or repeating elements based on the length of another object. `list_along()` creates a list of a specified length, and `rep_along()` repeats elements. ```r # Creating a list along the length of a vector list_along(1:5, "a") # Repeating elements along the length of a vector rep_along(1:5, 0) ``` -------------------------------- ### Selection with vars() and tidyselect in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Details the updated support in map_at(), lmap_at(), and modify_at() for selection using vars() and tidyselect, enabling more powerful subsetting capabilities. ```r library(purrr) library(dplyr) # For vars() my_list <- list(a = 1, b = 2, c = 3, d = 4) # Using vars() to select columns by name modified_list <- modify_at(my_list, vars(a, c), ~ . * 10) print(modified_list) # Output: list(a = 10, b = 2, c = 30, d = 4) # Using tidyselect syntax (e.g., starts_with) modified_list_tidy <- map_at(my_list, vars(starts_with("b")), ~ . + 100) print(modified_list_tidy) # Output: list(a = 1, b = 102, c = 3, d = 4) ``` -------------------------------- ### Handle modify_tree error: is_node must be a function Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/modify-tree.md This example demonstrates an error condition in `modify_tree` where the `is_node` argument is provided as a numeric value instead of a function. It illustrates the package's strictness on input types for functions. ```r modify_tree(list(), is_node = 1) ``` -------------------------------- ### Using pluck() for Deep Data Structure Indexing in R Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Demonstrates the use of `pluck()` for more readable extraction of elements from nested data structures. It contrasts the verbose, multi-step accessor syntax with the concise `pluck()` pipe-based approach, improving code clarity. ```r # Syntax-heavy extraction: accessor(x[[1]])$foo # Equivalent pluck: x |> pluck(1, accessor, "foo") ``` -------------------------------- ### Coerce to Character Vectors in Purrr Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/coerce.md Highlights the `coerce_chr()` function's inability to coerce logical, integer, or numeric types to character vectors. The provided examples demonstrate that these coercions fail and result in errors, contrary to expected behavior. ```R expect_equal(coerce_chr(TRUE), "TRUE") # Error: ! Can't coerce from a logical value to a string. expect_equal(coerce_chr(1L), "1") # Error: ! Can't coerce from an integer to a string. expect_equal(coerce_chr(1.5), "1.500000") # Error: ! Can't coerce from a number to a string. ``` -------------------------------- ### Input validation for list_simplify Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-simplify.md Shows how list_simplify validates its primary input 'x' to ensure it is a list. It also demonstrates the validation for the 'strict' argument, which must be TRUE or FALSE. ```r list_simplify(1:5) ``` ```r list_simplify(list(), strict = NA) ``` -------------------------------- ### Error Handling in flatten_dfr() and flatten_dfc() in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Documents that flatten_dfr() and flatten_dfc() now abort with an error if the dplyr package is not installed, ensuring required dependencies are met. ```r library(purrr) # Example data list_data <- list(list(a = 1, b = 2), list(a = 3, b = 4)) # If dplyr is not installed, the following calls will now error: # tryCatch({ # flatten_dfr(list_data) # }, error = function(e) { # print(e$message) # }) # # tryCatch({ # flatten_dfc(list_data) # }, error = function(e) { # print(e$message) # }) ``` -------------------------------- ### Deprecated imap_raw Function in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/map-raw.md Shows an example of the deprecated `imap_raw()` function from the purrr package. The recommended alternative is `imap_vec()`. ```r . <- imap_raw(list(), ~.x) ``` -------------------------------- ### Standardizing Reverse Iteration with .dir Argument in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Demonstrates the standardization of reverse iteration using the .dir argument in purrr functions, replacing deprecated functions like reduce_right() and accumulate_right(). ```r library(purrr) # reduce() with .dir = "backward" replaces reduce_right() f <- function(x, y) x + y # Before: reduce_right(1:3, f) # Computes f(f(3, 2), 1) = (3 + 2) + 1 = 6 # After: reduce(1:3, f, .dir = "backward") # Computes f(1, f(2, 3)) = 1 + (2 + 3) = 6 print(reduce(1:3, f, .dir = "backward")) # To replicate reduce_right() exactly, reverse the vector and use left reduction # print(reduce(rev(1:3), f)) # accumulate() with .dir = "backward" replaces accumulate_right() # Before: accumulate_right(1:3, f) # After: accumulate(1:3, f, .dir = "backward") print(accumulate(1:3, f, .dir = "backward")) # Output: c(1, 3, 6) # detect() with .dir = "backward" replaces .right = TRUE x <- 1:5 # Before: detect(x, ~ . > 3, .right = TRUE) # After: detect(x, ~ . > 3, .dir = "backward") print(detect(x, ~ . > 3, .dir = "backward")) # Output: 5 ``` -------------------------------- ### Using Formula Shorthand with ..1, ..2 Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Formula functions in purrr now support positional argument referencing using `..1`, `..2`, etc. This allows for concise definition of functions with more than two arguments directly within purrr functions. The input is a formula and the output is a function. ```R library(purrr) # Example: Function with three arguments using formula shorthandmap(1:3, ~ ..1 + ..2 + ..3, .y = 10, .z = 100) # Expected output: list(111, 112, 113) ``` -------------------------------- ### Deprecated pmap_raw Function in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/map-raw.md Provides a code example for the deprecated `pmap_raw()` function in purrr. The package suggests using `pmap_vec()` instead. ```r . <- pmap_raw(list(), ~.x) ``` -------------------------------- ### list_modify() Input Validation: Non-list Input Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-modify.md Demonstrates the error when `list_modify()` receives an input that is not a list. The function expects the primary argument `.x` to be a list. ```r list_modify(1:3) ``` -------------------------------- ### Plucking and Indexing with purrr (R) Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Demonstrates the enhanced `pluck()` function in purrr, including its new name `pluck_depth()`, requirement for length 1 indices, reporting of correct types, acceptance of negative integers for right-indexing, and failure with named inputs to `...`. It also covers how `pluck()` handles 0-length vectors and modification of non-existing locations with `pluck<-`/`assign_in()`. ```r library(purrr) x <- list(a = list(b = 1)) pluck(x, "a", "b") # Access nested element pluck(x, c("a", "b")) # Also works pluck(x, 1, 1) # Using numeric indices pluck(x, -1, -1) # Negative indexing from the right # pluck(x, "a", "b", name = "c") # Fails with named inputs to ... # pluck(x, "a", "c") # Reports correct type if index is unexpected # pluck_depth(x) # Replaces vec_depth() # pluck(list(), "a") # Handles 0-length vectors # pluck(list(), "a", default = 0) # Default value # assign_in(list(), c("a", "b"), 5) # Modifies non-existing locations ``` -------------------------------- ### rdunif Error: Non-numeric 'a' Parameter (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-utils.md Illustrates an error condition for the rdunif function when the 'a' parameter is not a numeric type. The function expects 'a' to be numeric. ```r rdunif(1000, 1, "a") ``` -------------------------------- ### Create Rate Objects with rate_backoff() and rate_delay() in R Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Demonstrates the creation of rate objects using rate_backoff() for exponential delays and rate_delay() for constant delays. These objects can be passed to functions like insistently() or slowly() to control function execution timing. ```r library(purrr) # Exponential backoff rate backoff_rate <- rate_backoff(pause_min = 1, pause_max = 10) # Constant delay rate delay_rate <- rate_delay(pause = 2) # Example usage with insistently (hypothetical) # insistently(my_function, rate = backoff_rate) # insistently(my_function, rate = delay_rate) # Example usage with slowly (hypothetical) # slowly(my_function, rate = backoff_rate) # slowly(my_function, rate = delay_rate) # Lower level function # rate_sleep(backoff_rate) ``` -------------------------------- ### Reduce2 with Empty List (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/reduce.md Highlights that `reduce2()`, similar to `reduce()`, requires an initial value (`.init`) when the input list `.x` is empty. Without `.init`, the function cannot proceed. ```r reduce2(list()) ``` -------------------------------- ### Validate lmap function argument type in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/lmap.md Shows how `lmap` validates that the mapping function (`.f`) is a function. Passing an environment instead of a function results in an error. ```r library(purrr) lmap(list(1), environment()) # Expected Error: Error in `lmap()`: # ! Can't convert `.f`, an environment, to a function. ``` -------------------------------- ### list_merge() Input Validation: Non-list Input Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-modify.md Demonstrates the error when `list_merge()` is called with an input that is not a list. The function requires its primary argument `.x` to be of type list. ```r list_merge(1:3) ``` -------------------------------- ### Strict simplification errors in list_simplify Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-simplify.md Illustrates scenarios where strict simplification in list_simplify leads to errors. This includes attempting to simplify a list of functions, incompatible data types within the list, and vectors of different sizes. ```r list_simplify(list(mean)) ``` ```r list_simplify(list(1, "a")) ``` ```r list_simplify(list(1, 1:2)) ``` ```r list_simplify(list(data.frame(x = 1), data.frame(x = 1:2))) ``` -------------------------------- ### Indexed Mapping with imap() Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md The `imap()` family of functions provides a shorthand for mapping over a list or vector while also having access to the index or names of the elements. It's equivalent to `map2(x, seq_along(x))` or `map2(x, names(x))`. It takes a list/vector and a function as input. ```R library(purrr) # Example: Using imap to access element value and its index my_list <- list("a", "b", "c") imap(my_list, ~ paste(.x, "at index", .y)) # Expected output: list("a at index 1", "b at index 2", "c at index 3") # Example with named list my_named_list <- list(first = 1, second = 2) imap(my_named_list, ~ paste(.x, "is named", .y)) # Expected output: list("1 is named first", "2 is named second") ``` -------------------------------- ### Coercion Methods in purrr Mapping Functions (R) Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Demonstrates the strict coercion methods now used by `_lgl()`, `_int()`, and `_dbl()` in purrr, aligning with vctrs. It highlights deprecated coercions and new behaviors for converting logical, integer, and double vectors to character vectors, as well as the handling of fractional doubles to integers. ```r map_chr(TRUE, identity) # Deprecated map_chr(0L, identity) # Deprecated map_chr(1L, identity) # Deprecated map_int(1.5, identity) # Fails map_int(1, identity) # Works map_int(c(TRUE, FALSE), identity) # Succeeds map_dbl(c(TRUE, FALSE), identity) # Succeeds map_lgl(c(1L, 0L), identity) # Succeeds map_lgl(c(1, 0), identity) # Succeeds ``` -------------------------------- ### Compose Function Behavior in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Demonstrates how the compose() function in purrr has been updated to return an identity function when called without inputs and to support composition with lambda functions. It also shows the new .dir argument for controlling composition direction. ```r library(purrr) # compose() without inputs returns an identity function identity_func <- compose() print(identity_func(10)) # Output: 10 # compose() with lambdas composed_lambda <- compose(function(x) x + 1, ~ . * 2) print(composed_lambda(5)) # Output: 12 # compose() with .dir argument add_one <- function(x) x + 1 multiply_by_two <- function(x) x * 2 # Default (right-to-left) composed_rtl <- compose(add_one, multiply_by_two) print(composed_rtl(5)) # Output: 11 ( (5 * 2) + 1 ) # Left-to-right composition composed_ltr <- compose(add_one, multiply_by_two, .dir = "forward") print(composed_ltr(5)) # Output: 15 ( (5 + 1) * 2 ) ``` -------------------------------- ### Squashing Quosures with partial() in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/adverb-partial.md Demonstrates how `partial()` squashes quosures before printing, showing the resulting partialised function. This is useful for creating pre-filled function arguments. ```r library(purrr) foo <- function(x, y = 3, ...) { # Function body } partial(foo) ``` -------------------------------- ### Default Value for detect() in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Introduces the .default argument in detect() to specify a return value when no element satisfies the predicate, enhancing control over non-matches. ```r library(purrr) x <- 1:5 # Detect the first element greater than 10, with a default value result_found <- detect(x, ~ . > 10, .default = "Not Found") print(result_found) # Output: "Not Found" # Detect the first element greater than 3 result_not_found <- detect(x, ~ . > 3, .default = "Not Found") print(result_not_found) # Output: 4 ``` -------------------------------- ### rdunif Error: Non-numeric 'b' Parameter (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-utils.md Shows an error scenario for rdunif where the 'b' parameter is not numeric. The function requires 'b' to be a numeric value. ```r rdunif(1000, FALSE, 2) ``` -------------------------------- ### Deprecation of prepend in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-prepend.md The `prepend` function in the purrr R package is deprecated as of version 1.0.0. Users are advised to use `append(after = 0)` instead. This example demonstrates the deprecation warning. ```r `. <- prepend(1, 2)` ``` -------------------------------- ### Reduce Vector Elements to a Single Value (R) Source: https://context7.com/tidyverse/purrr/llms.txt Explains and demonstrates the `reduce()` function in purrr for combining vector elements into a single value using a binary function. Supports initial values and backward reduction. ```r library(purrr) # Sum using reduce 1:5 |> reduce(`+`) # Product 1:5 |> reduce(`*`) # Concatenate strings c("a", "b", "c", "d") |> reduce(paste, sep = "-") # With initial value 1:5 |> reduce(`+`, .init = 100) # Backward reduction 1:4 |> reduce(list, .dir = "backward") # Random walk simulation reduce(1:100, \(pos, step) pos + sample(c(-1, 1), 1), .init = 0) # Early termination with done() letters |> reduce(\(acc, x) { if (nchar(acc) > 10) return(done(acc)) paste0(acc, x) }) ``` -------------------------------- ### Function Conversion with as_function() in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md The `as_function()` utility, which converts formulas and other expressions into actual R functions, is now exported. This allows users to reliably create functions from various input types. ```r # Converting a formula to a function as_function(~ .x + 1)(5) # Converting a string to a function as_function("toupper")("hello") ``` -------------------------------- ### Validate lmap function return type in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/lmap.md Demonstrates how `lmap` validates that the mapping function returns a list. If a non-list value (like a number) is returned, `lmap` throws an informative error. ```r library(purrr) lmap(list(1), ~1) # Expected Error: Error in `lmap()`: # ! `.f(.x[[1]])` must return a list, not a number. ``` -------------------------------- ### list_merge() Input Validation: Duplicate Argument Names Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-modify.md Illustrates the error when `list_merge()` is used with duplicate names in the `...` arguments. Similar to `list_modify()`, all arguments in `...` must have unique names. ```r list_merge(list(x = 1), x = 2, x = 3) ``` -------------------------------- ### Setting Names with set_names() in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Provides `set_names()` as a snake-case alternative to `setNames()`. It offers stricter equality checking and more convenient defaults for use with pipes, such as `x |> set_names()` which is equivalent to `setNames(x, x)`. ```r # Setting names of a list or vector set_names(list(a = 1, b = 2), c("x", "y")) # Convenient default for pipes letters[1:3] |> set_names() ``` -------------------------------- ### Purrr map_vec: Enforcing output prototype (.ptype) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/map.md Shows how `map_vec()` can enforce a specific output type using the `.ptype` argument. It illustrates an error when the generated output cannot be coerced to the specified prototype. ```R map_vec(1:2, ~ factor("x"), .ptype = integer()) # Condition # Error in `map_vec()`: # ! Can't convert `[[1]]` > to . ``` -------------------------------- ### Control Argument Position with partial() in R Source: https://context7.com/tidyverse/purrr/llms.txt Demonstrates how to use the `partial()` function from the purrr package to fix some arguments of a function and control the position of the remaining arguments using `...`. This allows for creating specialized versions of functions. ```r library(purrr) # Control argument position with ... my_list <- partial(list, "first", ... = , "last") my_list("middle") #> [[1]] #> [1] "first" #> [[2]] #> [1] "middle" #> [[3]] #> [1] "last" ``` -------------------------------- ### Purrr map_int: Error location with names Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/map.md Shows how `map_int()` uses element names to report the location of errors, making debugging easier. It handles cases with and without names when errors occur. ```R map_int(c(a = 1, b = 2, c = 3), ~ fail_at_3(.x, stop("Error"))) # Condition # Error in `map_int()`: # i In index: 3. # i With name: c. # Caused by error in `fail_at_3()`: # ! Error ``` ```R map_int(c(a = 1, b = 2, 3), ~ fail_at_3(.x, stop("Error"))) # Condition # Error in `map_int()`: # i In index: 3. # Caused by error in `fail_at_3()`: # ! Error ``` -------------------------------- ### Replacing invoke() with exec() in R Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Demonstrates how to replace the retired `invoke()` function with `exec()` for evaluating function calls. `exec()` is reexported from the rlang package and supports tidy dots for argument passing. This change aims for more consistent function signature handling. ```r # Before: invoke(mean, list(na.rm = TRUE), x = 1:10) # After exec(mean, 1:10, !!!list(na.rm = TRUE)) ``` -------------------------------- ### Input recycling behavior in map2 Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/parallel.md Demonstrates the input recycling rules for `map2()`. It shows that inputs of different lengths will cause an error if they cannot be recycled to match. It also illustrates errors when recycling against an empty vector. ```R map2(1:2, 1:3, in_parallel(function(x, y) x + y)) ``` ```R map2(1:2, integer(), in_parallel(function(x, y) x + y)) ``` -------------------------------- ### list_modify() Input Validation: Duplicate Argument Names Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-modify.md Shows the error generated when `list_modify()` is provided with duplicate names in the `...` arguments. Each argument passed via `...` must have a unique name. ```r list_modify(list(x = 1), x = 2, x = 3) ``` -------------------------------- ### Setting Elements to NULL with purrr (R) Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Explains the updated behavior of `pluck<-`/`assign_in()` in purrr, which now sets elements to `NULL` instead of removing them. It also covers how `modify()`, `modify2()`, `modify_if()`, and `list_modify()` handle `NULL` values in replacement and how `zap()` can be used for explicit removal. ```r library(purrr) x <- list(a = 1, b = 2, c = 3) # Setting to NULL pluck(x, "b") <- NULL x # list(a = 1, b = NULL, c = 3) # Explicit removal using zap() pluck(x, "a") <- zap() x # list(b = NULL, c = 3) # Handling NULLs in modify functions modify(list(a = 1, b = 2), ~ NULL) # list(a = NULL, b = NULL) list_modify(list(a = 1, b = 2), a = NULL) # list(a = NULL, b = 2) list_modify(list(a = 1, b = 2), a = zap()) # list(b = 2) ``` -------------------------------- ### Enforce positional arguments for pluck/chuck in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/pluck.md Illustrates that `pluck()` and `chuck()` require arguments in `...` to be passed by position, not by name. Providing named arguments results in an error, guiding users to correct usage. ```R pluck(1, a = 1) chuck(1, a = 1) ``` -------------------------------- ### Compose Functions with compose() in R Source: https://context7.com/tidyverse/purrr/llms.txt Shows how to use the `compose()` function from the purrr package to chain multiple functions together. Functions are composed from right to left by default, but this can be reversed using `.dir = "forward"`. It also demonstrates splicing a list of functions. ```r library(purrr) # Compose functions (right to left by default) add1 <- function(x) x + 1 times2 <- function(x) x * 2 add1_then_times2 <- compose(times2, add1) # times2(add1(x)) add1_then_times2(5) #> [1] 12 # Left to right with .dir = "forward" times2_then_add1 <- compose(times2, add1, .dir = "forward") # add1(times2(x)) times2_then_add1(5) #> [1] 11 # Check if not null not_null <- compose(`!`, is.null) not_null(1) #> [1] TRUE not_null(NULL) #> [1] FALSE # Splice list of functions fns <- list(function(x) paste(x, "a"), function(x) paste(x, "b"), function(x) paste(x, "c")) pipeline <- compose(!!!fns, .dir = "forward") pipeline("start") #> [1] "start a b c" ``` -------------------------------- ### Type Conversion Errors in purrr Modifications Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/modify.md Shows examples of type conversion errors encountered when using purrr's modify functions. These errors occur when the provided modification function returns a type that cannot be coerced to the expected output type. ```r modify(1:3, ~"foo") modify_at(1:3, 1, ~"foo") modify_if(1:3, is_integer, ~"foo") modify2(1:3, "foo", ~.y) ``` -------------------------------- ### Input validation for list_simplify_internal Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-simplify.md Details input validation for the internal function list_simplify_internal. It covers the 'simplify' argument, ensuring it's TRUE, FALSE, or NA, and demonstrates an error when 'ptype' is specified with 'simplify = FALSE'. ```r list_simplify_internal(list(), simplify = 1) ``` ```r list_simplify_internal(list(), simplify = FALSE, ptype = integer()) ``` -------------------------------- ### list_modify() Input Validation: Mixed Named/Unnamed Arguments Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-modify.md Illustrates the error that occurs when `list_modify()` is called with a mix of named and unnamed arguments in the `...` parameter. All additional arguments must be consistently named or consistently unnamed. ```r list_modify(list(a = 1), 2, a = 2) ``` -------------------------------- ### rdunif Error: Non-unit Length 'b' Parameter (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-utils.md Highlights an error when the 'b' parameter for rdunif is provided as a vector instead of a single numeric value. The 'b' parameter must have a length of 1. ```r rdunif(1000, c(2, 3), 2) ``` -------------------------------- ### Relaxed Requirements for list_modify() and list_merge() in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Shows how list_modify() and list_merge() now have relaxed requirements regarding named vs. unnamed inputs, allowing for more flexible list manipulation. ```r library(purrr) list1 <- list(a = 1, b = 2) list2 <- list(c = 3, d = 4) list3 <- list(a = 5, e = 6) # list_modify() with mixed named and unnamed inputs (now allowed for ...) modified <- list_modify(list1, list2, f = 7) print(modified) # Output: list(a = 1, b = 2, c = 3, d = 4, f = 7) # list_merge() with positional matching for unnamed inputs merged_unnamed <- list_merge(list(1, 2), list(3, 4)) print(merged_unnamed) # Output: list(1, 2, 3, 4) # list_merge() with name matching for named inputs merged_named <- list_merge(list(a = 1, b = 2), list(a = 3, c = 4)) print(merged_named) # Output: list(a = 3, b = 2, c = 4) ``` -------------------------------- ### Coerce to Integer Vectors in Purrr Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/coerce.md Illustrates the `coerce_int()` function's limitations when coercing to integer vectors. It shows that attempting to coerce a number or a string to an integer results in an error, indicating that these types are not directly coercible to integers. ```R coerce_int(1.5) # Error: ! Can't coerce from a number to an integer. coerce_int("1") # Error: ! Can't coerce from a string to an integer. ``` -------------------------------- ### Support for Raw Vectors in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Introduces new functions in purrr designed to work with raw vectors, including map_raw, imap_raw, flatten_raw, and others. ```r library(purrr) raw_vec <- as.raw(c(0x01, 0x02, 0x03)) # Example using map_raw mapped_raw <- map_raw(raw_vec, function(x) x + 1) print(mapped_raw) # Output: Raw, 3 raw bytes of 02 03 04 # Example using flatten_raw list_of_raw <- list(as.raw(c(0x01, 0x02)), as.raw(c(0x03, 0x04))) flattened_raw <- flatten_raw(list_of_raw) print(flattened_raw) # Output: Raw, 4 raw bytes of 01 02 03 04 ``` -------------------------------- ### Access environment elements by name with chuck in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/pluck.md Demonstrates that `chuck()` can access elements within an environment by name. It also shows error handling for NA character input when accessing environment elements. ```R chuck(x, "y") chuck(x, NA_character_) ``` -------------------------------- ### Correct Filtering with cross2 in Purrr Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/deprec-cross.md Demonstrates the correct usage of the `.filter` argument in `cross2`. The predicate function must return a single `TRUE` or `FALSE` value. This example shows a valid predicate that filters based on a condition. ```r cross2(1:3, 1:3, .filter = ~ c(TRUE, TRUE)) ``` -------------------------------- ### Data Frame Mapping with dmap() and map() in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md The `map()` function now consistently returns a list. Data frame support is handled by `map_df()` and `dmap()`. `dmap()` applies a function to columns of a data frame, and supports sliced data frames for more granular operations. ```r # Mapping over a data frame's columns df <- data.frame(x = 1:3, y = 4:6) dmap(df, ~ .x * 2) # Using map() which now always returns a list map(list(1:3, 4:6), ~ .x + 1) ``` -------------------------------- ### Purrr map_vec: Output length and type enforcement Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/map.md Demonstrates the strict output requirements of `map_vec()`, which enforces that each output element must have a size of 1 and share a common type. Errors are shown for incorrect sizes and incompatible types. ```R map_vec(1:2, ~ rep(1, .x)) # Condition # Error in `map_vec()`: # ! `out[[2]]` must have size 1, not size 2. ``` ```R map_vec(1:2, ~ if (.x == 1) factor("x") else 1) # Condition # Error in `map_vec()`: # ! Can't combine `[[1]]` > and `[[2]]` . ``` -------------------------------- ### Transpose List with Simplification Errors (R) Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/list-transpose.md Shows silent simplification failures unless explicitly requested, and subsequent errors when simplification is attempted with incompatible types or sizes. ```R list_transpose(list(list(x = 1), list(x = "b")), simplify = TRUE) list_transpose(list(list(x = 1), list(x = 2:3)), simplify = TRUE) ``` -------------------------------- ### accumulate() Name Inheritance in purrr Source: https://github.com/tidyverse/purrr/blob/main/NEWS.md Describes how accumulate() now inherits names from its first input when .init is supplied, improving output clarity. ```r library(purrr) # accumulate() with .init and named input input_vec <- c(a = 1, b = 2, c = 3) # Before this change, names might not be preserved correctly. # Now, names from the first input are inherited. accumulated_result <- accumulate(input_vec, `+`, .init = 0) print(names(accumulated_result)) # Output: "a" "b" "c" print(accumulated_result) # Output: a=0 b=1 c=3 ``` -------------------------------- ### Handle NULL input with pluck/chuck in R Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/pluck.md Demonstrates that `pluck()` and `chuck()` cannot extract elements from NULL. They provide informative error messages indicating the inability to pluck from NULL at a specified level. ```R chuck(NULL, 1) ``` -------------------------------- ### Remove NULL and Empty Elements with compact() in R Source: https://context7.com/tidyverse/purrr/llms.txt The compact() function removes NULL and empty elements from lists. It is useful for cleaning up data structures before further processing. The example shows its application on a list containing various types of empty or NULL values. ```r library(purrr) list(a = 1, b = NULL, c = integer(0), d = NA, e = list()) |> compact() #> $a #> [1] 1 #> $d #> [1] NA ``` -------------------------------- ### Predicate Function Must Return Single TRUE/FALSE for head_while Source: https://github.com/tidyverse/purrr/blob/main/tests/testthat/_snaps/head-tail.md The `head_while` function in the purrr package requires a predicate function (`.p`) that returns a single `TRUE` or `FALSE` value. Providing a predicate that returns `NA` will result in an error, as demonstrated in the example. ```r head_while(1:3, ~NA) # Condition # Error in `head_while()`: # ! `.p()` must return a single `TRUE` or `FALSE`, not `NA`. ```