Download Latest Version purrr 1.1.0 source code.tar.gz (388.6 kB)
Email in envelope

Get an email when there's a new version of purrr

Home / v1.0.0
Name Modified Size InfoDownloads / Week
Parent folder
purrr 1.0.0 source code.tar.gz 2022-12-20 280.0 kB
purrr 1.0.0 source code.zip 2022-12-20 391.5 kB
README.md 2022-12-20 9.4 kB
Totals: 3 Items   680.9 kB 0

Breaking changes

Core purpose refinements

  • cross() and all its variants have been deprecated in favour of tidyr::expand_grid(). These functions were slow and buggy and we no longer think they are the right approach to solving this problem. See [#768] for more information.

  • update_list() (#858) and rerun() (#877), and the use of tidyselect with map_at() and friends (#874) have been deprecated. These functions use some form of non-standard evaluation which we now believe is a poor fit for purrr.

  • The lift_* family of functions has been deprecated. We no longer believe these to be a good fit for purrr because they rely on a style of function manipulation that is very uncommon in R code (#871).

  • prepend(), rdunif(), rbernoulli(), when(), and list_along() have all been deprecated (#925). It's now clear that they don't align with the core purpose of purrr.

  • splice() is deprecated because we no longer believe that automatic splicing makes for good UI. Instead use list2() + !!! or list_flatten() (#869).

Mapping

  • Use of map functions with expressions, calls, and pairlists has been deprecated (#961).

  • All map _raw() variants have been deprecated because they are of limited use and you can now use map_vec() instead (#903).

  • In map_chr(), automatic conversion from logical, integer, and double to character is now deprecated. Use an explicit as.character() if needed (#904).

Deprecation next steps

  • as_function() and the ...f argument to partial() are no longer supported. They have been defunct for quite some time.

  • Soft deprecated functions: %@%, reduce_right(), reduce2_right(), accumulate_right() are now fully deprecated. Similarly, the .lazy, .env, and .first arguments to partial(), and the .right argument to detect() and detect_index() are fully deprecated. Removing elements with NULL in list_modify() and list_merge() is now fully deprecated.

  • is_numeric() and is_scalar_numeric() have been removed. They have been deprecated since purrr 0.2.3 (Sep 2017).

  • invoke_*() is now deprecated. It was superseded in 0.3.0 (Jan 2019) and 3.5 years later, we have decided to deprecate it as part of the API refinement in the 1.0.0 release.

  • map_call() has been removed. It was made defunct in 0.3.0 (Jan 2019).

New features

  • *_at() can now take a function (or formula) that's passed the vector of element names and returns the elements to select.

  • New map_vec(), map2_vec(), and pmap_vec() work on all types of vectors, extending map_lgl(), map_int(), and friends so that you can easily work with dates, factors, date-times and more (#435).

  • New keep_at() and discard_at() that work like keep() and discard() but operation on element names rather than element contents (#817).

  • Some mapping functions have now a .progress argument to create a progress bar. See ?progress_bars (#149).

  • purrr is now licensed as MIT (#805).

  • modify(), modify_if(), modify_at(), and modify2() are no longer generics. We have discovered a simple implementation that no longer requires genericity and methods were only provided by a very small number of packages (#894).

  • purrr now uses the base pipe (|>) and anonymous function short hand (\(x)), in all examples. This means that examples will no longer work in R 4.0 and earlier so in those versions of R, the examples are automatically converted to a regular section with a note that they might not work (#936).

  • When map functions fail, they now report the element they failed at (#945).

  • New modify_tree() for recursively modifying nested data structures (#720).

Flattening and simplification

  • New list_c(), list_rbind(), and list_cbind() make it easy to c(), rbind(), or cbind() all of the elements in a list.

  • New list_simplify() reduces a list of length-1 vectors to a simpler atomic or S3 vector (#900).

  • New list_transpose() which automatically simplifies if possible (#875).

  • accumulate() and accumulate2() now both simplify the output if possible using vctrs. New arguments simplify and ptype allow you to control the details of simplification (#774, [#809]).

  • flatten() and friends are superseded in favour of list_flatten(), list_c(), list_cbind(), and list_rbind().

  • *_dfc() and *_dfr() have been superseded in favour of using the appropriate map function along with list_rbind() or list_cbind() (#912).

  • simplify(), simplify_all(), and as_vector() have been superseded in favour of list_simplify(). It provides a more consistent definition of simplification (#900).

  • transpose() has been superseded in favour of list_transpose() (#875). It has built-in simplification.

Tidyverse consistency

  • _lgl(), _int(), _int(), and _dbl() now use the same (strict) coercion methods as vctrs (#904). This means that:

    • map_chr(TRUE, identity), map_chr(0L, identity), and map_chr(1L, identity) are deprecated because we now believe that converting a logical/integer/double to a character vector should require an explicit coercion.

    • map_int(1.5, identity) now fails because we believe that silently truncating doubles to integers is dangerous. But note that map_int(1, identity) still works since no numeric precision is lost.

    • map_int(c(TRUE, FALSE), identity), map_dbl(c(TRUE, FALSE), identity), map_lgl(c(1L, 0L), identity) and map_lgl(c(1, 0), identity) now succeed because 1/TRUE and 0/FALSE should be interchangeable.

  • map2(), modify2(), and pmap() now use tidyverse recycling rules where vectors of length 1 are recycled to any size but all others must have the same length (#878).

  • map2() and pmap() now recycle names of their first input if needed (#783).

  • modify(), modify_if(), and modify_at() have been reimplemented using vctrs principles. This shouldn't have an user facing impact, but it does make the implementation much simpler.

Plucking

  • vec_depth() is now pluck_depth() and works with more types of input (#818).

  • pluck() now requires indices to be length 1 (#813). It also now reports the correct type if you supply an unexpected index.

  • pluck() now accepts negative integers, indexing from the right (#603).

  • pluck() and chuck() now fail if you provide named inputs to ... (#788).

  • pluck() no longer replaces 0-length vectors with default; it now only applies absent and NULL components (#480).

  • pluck<-/assign_in() can now modify non-existing locations (#704).

Setting with NULL

  • pluck<-/assign_in() now sets elements to NULL rather than removing them (#636). Now use the explicit zap() if you want to remove elements.

  • modify(), modify2(), and modify_if() now correctly handle NULLs in replacement values (#655, [#746], [#753]).

  • list_modify()'s interface has been standardised. Modifying with NULL now always creates a NULL in the output (#810)

list_ functions`

  • New list_assign() which is similar to list_modify() but doesn't work recursively (#822).

  • list_modify() no longer recurses into data frames (and other objects built on top of lists that are fundamentally non-list like) (#810). You can revert to the previous behaviour by setting .is_node = is.list.

Minor improvements and bug fixes

  • capture_output() correctly uses conditionMessage() instead of directly interrogating the message field (#1010).

  • modify() no longer works with calls or pairlists.

  • modify_depth() is no longer a generic. This makes it more consistent with map_depth().

  • map_depth() and modify_depth() have a new is_node argument that allows you to control what counts as a level. The default uses vec_is_list() to avoid recursing into rich S3 objects like linear models or data.frames (#958, [#920]).

  • map_depth() and modify_depth() now correctly recurse at depth 1.

  • as_mapper() is now around twice as fast when used with character, integer, or list (#820).

  • possibly() now defaults otherwise to NULL.

  • modify_if(.else) is now actually evaluated for atomic vectors (@mgirlich, [#701]).

  • lmap_if() correctly handles .else functions (#847).

  • every() now correctly propagates missing values using the same rules as && (#751). Internally, it has become a wrapper around &&. This makes it consistent with && and also with some() which has always been a wrapper around || with the same propagation rules.

  • every() and some() now properly check the return value of their predicate function. It must now return a TRUE, FALSE, or NA.

  • Greatly improved performance of functions created with partial() (#715). Their invocation is now as fast as for functions creating manually.

  • partial() no longer inlines the function in the call stack. This fixes issues when partial() is used with lm() for instance (#707).

Source: README.md, updated 2022-12-20