All functions and arguments deprecated in purrr 0.3.0 have nowbeen removed. This includes%@%,accumulate_right(),at_depth(),cross_d(),cross_n(),reduce2_right(), andreduce_right().
All functions that were soft-deprecated in purrr 1.0.0 are nowfully deprecated. They will be removed in a future release. Thisincludes:invoke_*(),lift_*(),cross*(),prepend(),splice(),rbernoulli(),rdunif(),when(),update_list(),*_raw(),vec_depth().
map_chr() no longer coereces from logical, integer,or double to strings.
every(),some(), andnone() now require that.p return logicalscalarTRUE,FALSE, orNA.Previously,NA was allowed to be a non-logicalNA, and would be coerced to a logicalNA.
New “getting started” vignette,vignette("purrr")(#915,
every(),some(), andnone() are now more performant. They are now as fast as orfaster than their equivalentany(map_lgl()) orall(map_lgl()) calls (#1036,
as_mapper.default() optimized by removing specialnamed argument handling for primitive functions (
list_flatten() gains anis_nodeparameter taking a predicate function that determines whether an inputelement is a node or a leaf (
in_parallel() now accepts objects, including helperfunctions, supplied to... for all locally-definedfunctions (#1208).
in_parallel() now works in conjunction with stringand list values supplied to the.progress argument of mapfunctions (#1203).
map(),map2(), andpmap()now automatically set the correct environment so thatformat strings to access to local variables (
map_vec() no longer fails on empty named lists(#1206).
purrr now requires R >= 4.1, so we can rely on the base pipeand lambda syntax (#1177).
purrr gainsin_parallel() to support parallel anddistributed maps, powered by {mirai}. See?in_parallel formore details (
Varies fixed to bring purrr back into compliance with R CMD check(@shikokuchuo,
Added missingimap_vec() (#1084)
list_transpose() now asserts that it does not workon data frames (
Fixed valgrind issue.
Deprecation infrastructure inmap_chr() now has muchless overhead leading to improved performance (#1089).
purrr now requires R 3.5.0.
As of purrr 1.0.0, themap() family of functionswraps all errors generated by.f inside an wrapper errorthat tracks the iteration index. As of purrr 1.0.1, this error now has acustom class (purrr_error_indexed),locationandname fields, and is documented in?purrr_error_indexed (#1027).
map() errors with named inputs also report the nameof the element that errored.
Fixed an issue where progress bars weren’t being closed when userinterrupts or errors were encountered during amap() call(#1024).
Fixed an invalid C signature forpluck()(#1018).
SetBiarch: true to build purrr on 32-bit Windows onR < 4.2.0 (#1017).
cross() and all its variants have been deprecated infavour oftidyr::expand_grid(). These functions were slowand buggy and we no longer think they are the right approach to solvingthis problem. See #768 for more information.
update_list() (#858) andrerun()(#877), and the use of tidyselect withmap_at() and friends(#874) have been deprecated. These functions use some form ofnon-standard evaluation which we now believe is a poor fit forpurrr.
Thelift_* family of functions has been deprecated.We no longer believe these to be a good fit for purrr because they relyon a style of function manipulation that is very uncommon in R code(#871).
prepend(),rdunif(),rbernoulli(),when(), andlist_along() have all been deprecated (#925). It’s nowclear that they don’t align with the core purpose of purrr.
splice() is deprecated because we no longer believethat automatic splicing makes for good UI. Instead uselist2() +!!! orlist_flatten()(#869).
Use of map functions with expressions, calls, and pairlists hasbeen deprecated (#961).
All map_raw() variants have been deprecated becausethey are of limited use and you can now usemap_vec()instead (#903).
Inmap_chr(), automatic conversion from logical,integer, and double to character is now deprecated. Use an explicitas.character() if needed (#904).
Errors from.f are now wrapped in an additionalclass that gives information about where the error occurred(#945).
as_function() and the...f argument topartial() are no longer supported. They have been defunctfor quite some time.
Soft deprecated functions:%@%,reduce_right(),reduce2_right(),accumulate_right() are now fully deprecated. Similarly, the.lazy,.env, and.first argumentstopartial(), and the.right argument todetect() anddetect_index() are fullydeprecated. Removing elements withNULL inlist_modify() andlist_merge() is now fullydeprecated.
is_numeric() andis_scalar_numeric()have been removed. They have been deprecated since purrr 0.2.3 (Sep2017).
invoke_*() is now deprecated. It was superseded in0.3.0 (Jan 2019) and 3.5 years later, we have decided to deprecate it aspart of the API refinement in the 1.0.0 release.
map_call() has been removed. It was made defunct in0.3.0 (Jan 2019).
*_at() can now take a function (or formula) that’spassed the vector of element names and returns the elements toselect.
Newmap_vec(),map2_vec(), andpmap_vec() work on all types of vectors, extendingmap_lgl(),map_int(), and friends so that youcan easily work with dates, factors, date-times and more(#435).
Newkeep_at() anddiscard_at() thatwork likekeep() anddiscard() but operationon element names rather than element contents (#817).
Some mapping functions have now a.progress argumentto create a progress bar. See?progress_bars(#149).
purrr is now licensed as MIT (#805).
modify(),modify_if(),modify_at(), andmodify2() are no longergenerics. We have discovered a simple implementation that no longerrequires genericity and methods were only provided by a very smallnumber of packages (#894).
purrr now uses the base pipe (|>) and anonymousfunction short hand (\(x)), in all examples. This meansthat examples will no longer work in R 4.0 and earlier so in thoseversions of R, the examples are automatically converted to a regularsection with a note that they might not work (#936).
When map functions fail, they now report the element they failedat (#945).
Newmodify_tree() for recursively modifying nesteddata structures (#720).
Newlist_c(),list_rbind(), andlist_cbind() make it easy toc(),rbind(), orcbind() all of the elements in alist.
Newlist_simplify() reduces a list of length-1vectors to a simpler atomic or S3 vector (#900).
Newlist_transpose() which automatically simplifiesif possible (#875).
accumulate() andaccumulate2() now bothsimplify the output if possible using vctrs. New argumentssimplify andptype allow you to control thedetails of simplification (#774, #809).
flatten() and friends are superseded in favour oflist_flatten(),list_c(),list_cbind(), andlist_rbind().
*_dfc() and*_dfr() have beensuperseded in favour of using the appropriate map function along withlist_rbind() orlist_cbind() (#912).
simplify(),simplify_all(), andas_vector() have been superseded in favour oflist_simplify(). It provides a more consistent definitionof simplification (#900).
transpose() has been superseded in favour oflist_transpose() (#875). It has built-insimplification.
_lgl(),_int(),_int(),and_dbl() now use the same (strict) coercion methods asvctrs (#904). This means that:
map_chr(TRUE, identity),map_chr(0L, identity), andmap_chr(1L, identity) are deprecated because we now believethat converting a logical/integer/double to a character vector shouldrequire an explicit coercion.
map_int(1.5, identity) now fails because we believethat silently truncating doubles to integers is dangerous. But note thatmap_int(1, identity) still works since no numeric precisionis lost.
map_int(c(TRUE, FALSE), identity),map_dbl(c(TRUE, FALSE), identity),map_lgl(c(1L, 0L), identity) andmap_lgl(c(1, 0), identity) now succeed because 1/TRUE and0/FALSE should be interchangeable.
map2(),modify2(), andpmap() now use tidyverse recycling rules where vectors oflength 1 are recycled to any size but all others must have the samelength (#878).
map2() andpmap() now recycle names oftheir first input if needed (#783).
modify(),modify_if(), andmodify_at() have been reimplemented using vctrs principles.This shouldn’t have an user facing impact, but it does make theimplementation much simpler.
vec_depth() is nowpluck_depth() andworks 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 unexpectedindex.
pluck() now accepts negative integers, indexing fromthe right (#603).
pluck() andchuck() now fail if youprovide named inputs to … (#788).
pluck() no longer replaces 0-length vectors withdefault; it now only applies absent andNULLcomponents (#480).
pluck<-/assign_in() can now modifynon-existing locations (#704).
pluck<-/assign_in() now setselements toNULL rather than removing them (#636). Now usethe explicitzap() if you want to remove elements.
modify(),modify2(), andmodify_if() now correctly handleNULLs inreplacement values (#655, #746, #753).
list_modify()’s interface has been standardised.Modifying withNULL now always creates aNULLin the output (#810)
list_ functionsNewlist_assign() which is similar tolist_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-listlike) (#810). You can revert to the previous behaviour by setting.is_node = is.list.
capture_output() correctly usesconditionMessage() instead of directly interrogating themessage field (#1010).
modify() no longer works with calls orpairlists.
modify_depth() is no longer a generic. This makes itmore consistent withmap_depth().
map_depth() andmodify_depth() have anewis_node argument that allows you to control what countsas a level. The default usesvec_is_list() to avoidrecursing into rich S3 objects like linear models or data.frames (#958,#920).
map_depth() andmodify_depth() nowcorrectly recurse at depth 1.
as_mapper() is now around twice as fast when usedwith character, integer, or list (#820).
possibly() now defaultsotherwise toNULL.
modify_if(.else) is now actually evaluated foratomic vectors (
lmap_if() correctly handles.elsefunctions (#847).
every() now correctly propagates missing valuesusing the same rules as&& (#751). Internally, ithas become a wrapper around&&. This makes itconsistent with&& and also withsome() which has always been a wrapper around|| with the same propagation rules.
every() andsome() now properly checkthe return value of their predicate function. It must now return aTRUE,FALSE, orNA.
Greatly improved performance of functions created withpartial() (#715). Their invocation is now as fast as forfunctions creating manually.
partial() no longer inlines the function in the callstack. This fixes issues whenpartial() is used withlm() for instance (#707).
Fixed issue inlist_modify() that prevented listsfrom being removed withzap() (
Added documentation for exporting functions created with purrradverb (@njtierney,#668). See?faq-adverbs-export.
Addednone(), which tests that a predicate is falsefor all elements (the opposite ofevery()) (
Maintenance release.
The documentation ofmap() and its variants has beenimproved by@surdinaas part of the Tidyverse Developer Day (
purrr now depends on R 3.2 or greater.
reduce() now forces arguments (#643).
Fixed an issue inpartial() with generic functions(#647).
negate() now works with generic functions andfunctions with early returns.
compose() now works with generic functions again(#629, #639). Its set of unit tests was expanded to cover many edgecases.
prepend() now works with empty lists (
modify() and variants are now wrapping[[<- instead of[<-. This changeincreases the genericity of these functions but might cause differentbehaviour in some cases.
For instance, the[[<- for data frames is stricterthan the[<- method and might throw errors instead ofwarnings. This is the case when assigning a longer vector than thenumber of rows.[<- truncates the vector with a warning,[[<- fails with an error (as is appropriate).
modify() and variants now return the same type asthe input when the input is an atomic vector.
All functionals taking predicate functions (likekeep(),detect(),some()) gotstricter. Predicate functions must now return a singleTRUEorFALSE.
This change is meant to detect problems early with a more meaningfulerror message.
Newchuck() function. This is a strict variant ofpluck() that throws errors when an element does not existinstead of returningNULL (
Newassign_in() andpluck<-functions. They modify a data structure at an existing plucklocation.
Newmodify_in() function to map a function at apluck location.
pluck() now dispatches properly with S3 vectors. Thevector class must implement alength() method for numericindexing and anames() method for string indexing.
pluck() now supports primitive functions(#404).
New.else argument formap_if() andmodify_if(). They take an alternative function that ismapped over elements of the input for which the predicate functionreturnsFALSE (#324).
reduce(),reduce2(),accumulate(), andaccumulate2() now terminateearly when the function returns a value wrapped withdone()(#253). When an emptydone() is returned, the value at thelast iteration is returned instead.
Functions taking predicates (map_if(),keep(),some(),every(),keep(), etc) now fail with an informative message when thereturn value is notTRUE orFALSE (#470).
This is a breaking change forevery() andsome() which were documented to be more liberal in thevalues they accepted as logical (any vector was consideredTRUE if not a singleFALSE value, no matterits length). These functions signal soft-deprecation warnings instead ofa hard failure.
Edit (purr 0.4.0):every() andsome() neverissued deprecation warnings because of a technical issue. We didn’t fixthe warnings in the end, and using predicates returningNAis no longer considered deprecated. If you need to useevery() andsome() in contexts whereNA propagation is unsafe, e.g. inif ()conditions, make sure to use safe predicate functions likeis_true().
modify() and variants are now implemented usinglength(),[[, and[[<-methods. This implementation should be compatible with most vectorclasses.
Newmodify2() andimodify() functions.These work likemap() andimap() but preservethe type of.x in the return value.
pmap() andpwalk() now preserve classfor inputs offactor,Date,POSIXct and other atomic S3 classes with an appropriate[[ method (#358,
modify(),modify_if() andmodify_at() now preserve the class of atomic vectorsinstead of promoting them to lists. New S3 methods are provided forcharacter, logical, double, and integer classes (
By popular request,at_depth() has been brought backasmap_depth(). Likemodify_depth(), itapplies a function at a specified level of a data structure. However, ittransforms all traversed vectors up to.depth to bare lists(#381).
map_at(),modify_at() andlmap_at() accept negative values for.at,ignoring elements at those positions.
map() andmodify() now work with callsand pairlists (#412).
modify_depth() now modifies atomic leaves as well.This makesmodify_depth(x, 1, fn) equivalent tomodify(x, fn) (#359).
Newaccumulate2() function which is toaccumulate() whatreduce2() is toreduce().
Newrate_backoff() andrate_delay()functions to create rate objects. You can pass rates toinsistently(),slowly(), or the lower levelfunctionrate_sleep(). This will cause a function to waitfor a given amount of time with exponential backoff (increasingly largerwaiting times) or for a constant delay.
insistently(f) modifies a function,f,so that it is repeatedly called until it succeeds (
slowly() modifies a function so that it waits for agiven amount of time between calls.
partial()The interface ofpartial() has been simplified. It nowsupports quasiquotation to control the timing of evaluation, and therlang::call_modify() syntax to control the position ofpartialised arguments.
partial() now supports empty... =argument to specify the position of future arguments, relative topartialised ones. This syntax is borrowed from (and implemented with)rlang::call_modify().
To prevent partial matching of... on...f,the latter has been renamed to.f, which is more consistentwith other purrr function signatures.
partial() now supports quasiquotation. When youunquote an argument, it is evaluated only once at function creationtime. This is more flexible than the.lazy argument sinceyou can control the timing of evaluation for each argument.Consequently,.lazy is soft-deprecated (#457).
Fixed an infinite loop when partialised function is given thesame name as the original function (#387).
partial() now callsas_closure() onprimitive functions to ensure argument matching (#360).
The.lazy argument ofpartial() issoft-deprecated in favour of quasiquotation:
# Beforepartial(fn,u =runif(1),n =rnorm(1),.lazy =FALSE)# Afterpartial(fn,u =!!runif(1),n =!!rnorm(1))# All constantpartial(fn,u =!!runif(1),n =rnorm(1))# First constantThe tibble package is now in Suggests rather than Imports. Thisbrings the hard dependency of purrr to just rlang and magrittr.
compose() now returns an identity function whencalled without inputs.
Functions created withcompose() now have the sameformal parameters as the first function to be called. They also featurea more informative print method that prints all composed functions inturn (@egnha,#366).
New.dir argument incompose(). Whenset to"forward", the functions are composed from left toright rather than right to left.
list_modify() now supports thezap()sentinel (reexported from rlang) to remove elements from lists.Consequently, removing elements with the ambiguous sentinelNULL is soft-deprecated.
The requirements oflist_modify() andlist_merge() have been relaxed. Previously it required boththe modified lists and the inputs to be either named or unnamed. Thisrestriction now only applies to inputs in.... When inputsare all named, they are matched to the list by name. When they are allunnamed, they are matched positionally. Otherwise, this is anerror.
Fixed ordering of names returned byaccumulate_right() output. They now correspond to the orderof inputs.
Fixed names ofaccumulate() output when.init is supplied.
compose() now supports composition with lambdas(@ColinFay,#556)
Fixed apmap() crash with empty lists on the Win32platform (#565).
modify_depth now has.ragged argumentevaluates correctly toTRUE by default when.depth < 0 (
accumulate() now inherits names from their firstinput (@AshesITR,#446).
attr_getter() no longer uses partial matching. Forexample, if anx object has alabels attributebut nolabel attribute,attr_getter("label")(x) will no longer extract thelabels attribute (#460,
flatten_dfr() andflatten_dfc() nowaborts if dplyr is not installed. (#454)
imap_dfr() now works with.id argumentis provided (#429)
list_modify(),update_list() andlist_merge() now handle duplicate duplicate argument namescorrectly (#441,
map_raw,imap_raw,flatten_raw,invoke_map_raw,map2_raw andpmap_raw added to support rawvectors. (#455,
flatten() now supports raw and complexelements.
array_branch() andarray_tree() nowretain thedimnames() of the input array (#584,
pluck() no longer flattens lists of arguments. Youcan still do it manually with!!!. This change is forconsistency with other dots-collecting functions of thetidyverse.
map_at(),lmap_at() andmodify_at() now supports selection usingvars() andtidyselect (
Note that for now you need to importvars() from dplyror call it qualified likedplyr::vars(). It will bereexported from rlang in a future release.
detect() now has a .default argument to specify thevalue returned when nothing is detected (#622,
.dir argumentsWe have standardised the purrr API for reverse iteration with acommon.dir argument.
reduce_right() is soft-deprecated and replaced by anew.dir argument ofreduce():
# Before:reduce_right(1:3, f)# After:reduce(1:3, f, .dir = "backward")Note that the details of the computation have changed. Whereasreduce_right() computedf(f(3, 2), 1), it nowcomputesf(1, f(2, 3)). This is the standard way ofreducing from the right.
To produce the exact same reduction asreduce_right(),simply reverse your vector and use a left reduction:
# Before:reduce_right(1:3, f)# After:reduce(rev(1:3), f)reduce2_right() is soft-deprecated withoutreplacement. It is not clear what algorithmic properties should a rightreduction have in this case. Please reach out if you know about a usecase for a right reduction with a ternary function.
accumulate_right() is soft-deprecated and replacedby the new.dir argument ofaccumulate(). Notethat the algorithm has slightly changed: the accumulated value is passedto the right rather than the left, which is consistent with a rightreduction.
# Before:accumulate_right(1:3, f)# After:accumulate(1:3, f, .dir = "backward")The.right argument ofdetect() anddetect_index() is soft-deprecated and renamed to.dir for consistency with other functions and clarity ofthe interface.
# Beforedetect(x, f, .right = TRUE)# Afterdetect(x, f, .dir = "backward")partial()The interface ofpartial() has been simplified (see moreaboutpartial() below):
The.lazy argument ofpartial() issoft-deprecated in favour of quasiquotation.
We had to rename...f to.f inpartial() in order to support... = argument(which would otherwise partial-match on...f). This alsomakespartial() more consistent with other purrr functionsignatures.
invoke()invoke() andinvoke_map() are retired infavour ofexec(). Note that retired functions are no longerunder active development, but continue to be maintained undefinitely inthe package.
invoke() is retired in favour of theexec() function, reexported from rlang.exec()evaluates a function call built from its inputs and supports tidydots:
# Before:invoke(mean,list(na.rm =TRUE),x =1:10)# Afterexec(mean,1:10,!!!list(na.rm =TRUE))Note that retired functions are not removed from the package and willbe maintained undefinitely.
invoke_map() is retired without replacement becauseit is more complex to understand than the corresponding code usingmap(),map2() andexec():
# 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))%@% is soft-deprecated, please use the operatorexported in rlang instead. The latter features an interface moreconsistent with@ as it uses NSE, supports S4 fields, andhas an assignment variant.
Removing elements from lists usingNULL inlist_modify() is soft-deprecated. Please use the newzap() sentinel reexported from rlang instead:
# Before: list_modify(x, foo = NULL) # After: list_modify(x, foo = zap())This change is motivated by the ambiguity ofNULL as adeletion sentinel becauseNULL is also a valid value inlists. In the future,NULL will set an element toNULL rather than removing the element.
rerun() is now in the questioning stage because weare no longer convinced NSE functions are a good fit for purrr. Also,rerun(n, x) can just as easily be expressed asmap(1:n, ~ x) (with the added benefit of being passed thecurrent index as argument to the lambda).
map_call() is defunct.
We noticed the following issues during reverse dependencieschecks:
Ifreduce() fails with this message:Error: `.x` is empty, and no `.init` supplied, this isbecausereduce() now returns.init when.x is empty. Fix the problem by supplying an appropriateargument to.init, or by providing special behaviour when.x has length 0.
The type predicates have been migrated to rlang. Consequently thebare-type-predicates documentation topic is no longer inpurrr, which might cause a warning if you cross-reference it.
purrr no longer depends on lazyeval or Rcpp (or dplyr, as of theprevious version). This makes the dependency graph of the tidyversesimpler, and makes purrr more suitable as a dependency of lower-levelpackages.
There have also been two changes to eliminate name conflicts betweenpurrr and dplyr:
order_by(),sort_by() andsplit_by() have been removed.order_by()conflicted withdplyr::order_by() and the complete familydoesn’t feel that useful. Use tibbles instead (#217).
contains() has been renamed tohas_element() to avoid conflicts with dplyr(#217).
The plucking mechanism used for indexing into data structures withmap() has been extracted into the functionpluck(). Plucking is often more readable to extract anelement buried in a deep data structure. Compare this syntax-heavyextraction which reads non-linearly:
accessor(x[[1]])$footo the equivalent pluck:
x |> pluck(1, accessor, "foo")as_function() is nowas_mapper()because it is a tranformation that makes sense primarily for mappingfunctions, not in general (#298)..null has been renamed to.default to better reflect its intent (#298)..default is returned whenever an element is absent or empty(#231, #254).
as_mapper() sanitises primitive functions bytransforming them to closures with standardised argument names (usingrlang::as_closure()). For instance+ istransformed tofunction(.x, .y) .x + .y. This results inproper argument matching so thatmap(1:10, partial(-, .x = 5)) produceslist(5 - 1, 5 - 2, ...).
Recursive indexing can now extract objects out of environments(#213) and S4 objects (#200), as well as lists.
attr_getter() makes it possible to extract fromattributes likemap(list(iris, mtcars), attr_getter("row.names")).
The argument list for formula-functions has been tweaked so thatyou can refer to arguments by position with..1,..2, and so on. This makes it possible to use the formulashorthand for functions with more than two arguments (#289).
possibly(),safely() and friends nolonger capture interrupts: this means that you can now terminate amapper using one of these with Escape or Ctrl + C (#314)
All map functions now treatNULL the same way as anempty vector (#199), and return an empty vector if any input is an emptyvector.
Allmap() functions now force their arguments in thesame way that base R does forlapply() (#191). This makesmap() etc easier to use when generating functions.
A new family of “indexed” map functions,imap(),imap_lgl() etc, provide a short-hand formap2(x, names(x)) ormap2(x, seq_along(x))(#240).
The data frame suffix_df has been (soft) deprecatedin favour of_dfr to more clearly indicate that it’s arow-bind. All variants now also have a_dfc for columnbinding (#167). (These will not be terribly useful untildplyr::bind_rows()/dplyr::bind_cols() havebetter semantics for vectors.)
A newmodify() family returns the same output of thetype as the input.x. This is in contrast to themap() family which always returns a list, regardless of theinput type.
The modify functions are S3 generics. However their default methodsshould be sufficient for most classes since they rely on the semanticsof[<-.modify.default() is thus ashorthand forx[] <- map(x, f).
at_depth() has been renamed tomodify_depth().
modify_depth() gains new.raggedargument, and negative depths are now computed relative to the deepestcomponent of the list (#236).
auto_browse(f) returns a new function thatautomatically callsbrowser() iff throws anerror (#281).
vec_depth() computes the depth (i.e. the number oflevels of indexing) or a vector (#243).
reduce2() andreduce2_right() make itpossible to reduce with a 3 argument function where the first argumentis the accumulated value, the second argument is.x, andthe third argument is.y (#163).
list_modify() extendsstats::modifyList() to replace by position if the list isnot named.(#201).list_merge() operates similarly tolist_modify() but combines instead of replacing(#322).
The legacy functionupdate_list() is basically aversion oflist_modify that evaluates formulas within thelist. It is likely to be deprecated in the future in favour of atidyeval interface such as a list method fordplyr::mutate().
Thanks to
All predicate functions are re-exported from rlang(#124).
compact() now works with standard mapper conventions(#282).
cross_n() has been renamed tocross().The_n suffix was removed for consistency withpmap() (originally calledmap_n() at the startof the project) andtranspose() (originally calledzip_n()). Similarly,cross_d() has beenrenamed tocross_df() for consistency withmap_df().
every() andsome() now returnNA if present in the input (#174).
invoke() uses a more robust approach to generate theargument list (#249) It no longer uses lazyeval to figure out whichenviroment a characterf comes from.
is_numeric() andis_scalar_numeric()are deprecated because they don’t test for what you might expect atfirst sight.
reduce() now throws an error if.x isempty and.init is not supplied.
Deprecated functionsflatmap(),map3(),map_n(),walk3(),walk_n(),zip2(),zip3(),zip_n() have beenremoved.
pmap() coerces data frames to lists to avoid theexpensive[.data.frame which provides security that isunneeded here (#220).
rdunif() checks its inputs for validity(#211).
set_names() can now take a function to tranform thenames programmatically (#276), and you can supply names in... to reduce typing even more more (#316).set_names() is now powered byrlang::set_names().
safely() now actually uses thequietargument (#296).
transpose() now matches by name if available (#164).You can override the default choice with the new.namesargument.
The function argument ofdetect() anddetect_index() have been renamed from.p to.f. This is because they have mapper semantics rather thanpredicate semantics.
This is a compatibility release with dplyr 0.6.0.
dmap(),dmap_at(),dmap_if(),invoke_rows(),slice_rows(),map_rows(),by_slice(),by_row(),andunslice() have been moved to purrrlyr. This is a bit ofan aggresive change but it allows us to make the dependencies muchlighter.Fix for dev tibble support.
as_function() now supports list arguments whichallow recursive indexing using either names or positions. They nowalways stop when encountering the first NULL (#173).
accumulate andreduce correctly passextra arguments to the worker function.
as_function() gains a.null argumentthat for character and numeric values allows you to specify what toreturn for null/absent elements (#110). This can be used with any mapfunction, e.g. map_int(x, 1, .null = NA)
as_function() is now generic.
Newis_function() that returnsTRUEonly for regular functions.
Fix crash on GCC triggered byinvoke_rows().
There are two handy infix functions:
x %||% y is shorthand forif (is.null(x)) y else x (#109).x %@% "a" is shorthand forattr(x, "a", exact = TRUE) (#69).accumulate() has been added to handle recursivefolding. It is shortand forReduce(f, .x, accumulate = TRUE) and follows a similarsyntax toreduce() (#145). A right-hand versionaccumulate_right() was also added.
map_df() row-binds output together. It’s theequivalent ofplyr::ldply() (#127)
flatten() is now type-stable and always returns alist. To return a simpler vector, useflatten_lgl(),flatten_int(),flatten_dbl(),flatten_chr(), orflatten_df().
invoke() has been overhauled to be more useful: itnow works similarly tomap_call() when.x isNULL, and hencemap_call() has been deprecated.invoke_map() is a vectorised complement toinvoke() (#125), and comes with typed variantsinvoke_map_lgl(),invoke_map_int(),invoke_map_dbl(),invoke_map_chr(), andinvoke_map_df().
transpose() replaceszip2(),zip3(), andzip_n() (#128). The name moreclearly reflects the intent (transposing the first and second levels oflist). It no longer has fields argument or the.simplifyargument; instead use the newsimplify_all()function.
safely(),quietly(), andpossibly() are experimental functions for working withfunctions with side-effects (e.g. printed output, messages, warnings,and errors) (#120).safely() is a version oftry() that modifies a function (rather than an expression),and always returns a list with two components,result anderror.
list_along() andrep_along() generalisethe idea ofseq_along(). (#122).
is_null() is the snake-case version ofis.null().
pmap() (parallel map) replacesmap_n()(#132), and has typed-variants suffixedpmap_lgl(),pmap_int(),pmap_dbl(),pmap_chr(), andpmap_df().
set_names() is a snake-case alternative tosetNames() with stricter equality checking, and moreconvenient defaults for pipes:x |> set_names() isequivalent tosetNames(x, x) (#119).
We are still figuring out what belongs in dplyr and what belongs inpurrr. Expect much experimentation and many changes with thesefunctions.
map() now always returns a list. Data frame supporthas been moved tomap_df() anddmap(). Thelatter supports sliced data frames as a shortcut for the combination ofby_slice() anddmap():x |> by_slice(dmap, fun, .collate = "rows"). Theconditional variantsdmap_at() anddmap_if()also support sliced data frames and will recycle scalar results to theslice size.
map_rows() has been renamed toinvoke_rows(). As other rows-based functionals, it collatesresults inside lists by default, but with column collation this functionis equivalent toplyr::mdply().
The rows-based functionals gain a.to option to namethe output column as well as a.collate argument. Thelatter allows to collate the output in lists (by default), on columns oron rows. This makes these functions more flexible and morepredictable.
as_function(), which converts formulas etc tofunctions, is now exported (#123).
rerun() is correctly scoped (#95)
update_list() can now modify an element calledx (#98).
map*() now use custom C code, rather than relying onlapply(),mapply() etc. The performancecharacteristcs are very similar, but it allows us greater control overthe output (#118).
map_lgl() now has second argument.f,not.p (#134).
flatmap() -> usemap() followed bythe appropriateflatten().
map_call() ->invoke().
map_n() ->pmap();walk_n() ->pwalk().
map3(x, y, z) ->map_n(list(x, y, z));walk3(x, y, z) ->pwalk(list(x, y, z))`