Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@

* `map_chr()` no longer coereces from logical, integer, or double to strings.

* `every()`, `some()`, and `none()` now require that `.p` return logical scalar `TRUE`, `FALSE`, or `NA`. Previously, `NA` was allowed to be a non-logical `NA`, and would be coerced to a logical `NA`.

## Minor improvements and bug fixes

* New "getting started" vignette, `vignette("purrr")` (#915, @ogolovkina).

* `every()`, `some()`, and `none()` are now more performant. They are now as fast as or faster than their equivalent `any(map_lgl())` or `all(map_lgl())` calls (#1036, @ErdaradunGaztea).

* `as_mapper.default()` optimized by removing special named argument handling for primitive functions (@mtcarsalot, #1088).

* `list_flatten()` gains an `is_node` parameter taking a predicate function that determines whether an input element is a node or a leaf (@salim-b, #1179).
Expand Down
59 changes: 34 additions & 25 deletions R/every-some-none.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,48 @@
#' # unsafe (e.g. in `if ()` conditions), make sure to use safe predicates:
#' if (some(list(NA, FALSE), rlang::is_true)) "foo" else "bar"
every <- function(.x, .p, ...) {
.p <- as_predicate(.p, ..., .mapper = TRUE, .allow_na = TRUE)

val <- TRUE
for (i in seq_along(.x)) {
val <- val && .p(.x[[i]], ...)

if (is_false(val)) {
return(FALSE)
}
}

val
satisfies_predicate(.x, .p, ..., .purrr_predicate = "every")
}

#' @export
#' @rdname every
some <- function(.x, .p, ...) {
.p <- as_predicate(.p, ..., .mapper = TRUE, .allow_na = TRUE)

val <- FALSE
for (i in seq_along(.x)) {
val <- val || .p(.x[[i]], ...)

if (is_true(val)) {
return(TRUE)
}
}

val
satisfies_predicate(.x, .p, ..., .purrr_predicate = "some")
}

#' @export
#' @rdname every
none <- function(.x, .p, ...) {
every(.x, negate(.p), ...)
satisfies_predicate(.x, .p, ..., .purrr_predicate = "none")
}

satisfies_predicate <- function(
.x,
.p,
...,
.purrr_predicate,
.purrr_user_env = caller_env(2),
.purrr_error_call = caller_env()
) {
# Not using `as_predicate()` as R level predicate result checks are too slow.
# Checks are done at the C level instead (#1169). Also, `NA` propagates
# through these functions, which `as_predicate()` doesn't allow.
.p <- as_mapper(.p, ...)

# Consistent with `map()`
.x <- vctrs_vec_compat(.x, .purrr_user_env)
obj_check_vector(.x, arg = ".x", call = .purrr_error_call)

n <- vec_size(.x)

i <- 0L

# We refer to `.p`, `.x`, `i`, `...`, and `.purrr_error_call` all from C level
switch(
.purrr_predicate,
every = .Call(every_impl, environment(), n, i),
some = .Call(some_impl, environment(), n, i),
none = .Call(none_impl, environment(), n, i),
abort("Unreachable", .internal = TRUE)
)
}
14 changes: 5 additions & 9 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ as_predicate <- function(
.fn,
...,
.mapper,
.allow_na = FALSE,
.purrr_error_call = caller_env(),
.purrr_error_arg = caller_arg(.fn)
) {
Expand All @@ -75,10 +74,6 @@ as_predicate <- function(
out <- .fn(...)

if (!is_bool(out)) {
if (is_na(out) && .allow_na) {
# Always return a logical NA
return(NA)
}
Comment on lines -78 to -81
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed this because no one else uses it

This was a fairly weird bit of purrr. every(), none(), and some() strictly required the result of .p to be TRUE or FALSE with no casting, but were lax about NA, allowing NA_character_ and friends, which I don't really think made any sense.

I've changed this in the C code to strictly require a scalar logical vector, and added tests about this.

This is a breaking change, but hopefully a very minor one.

cli::cli_abort(
"{.fn { .purrr_error_arg }} must return a single `TRUE` or `FALSE`, not {.obj_type_friendly {out}}.",
arg = .purrr_error_arg,
Expand Down Expand Up @@ -115,8 +110,9 @@ vctrs_list_compat <- function(
}

# When we want to use vctrs, but treat lists like purrr does
# Treat data frames and S3 scalar lists like bare lists.
# But ensure rcrd vctrs retain their class.
#
# Treats data frames and S3 scalar lists like bare lists.
# But ensures rcrd vctrs retain their class.
vctrs_vec_compat <- function(x, user_env) {
if (inherits(x, "by")) {
class(x) <- NULL
Expand All @@ -127,7 +123,7 @@ vctrs_vec_compat <- function(x, user_env) {
} else if (is.pairlist(x)) {
lifecycle::deprecate_soft(
when = "1.0.0",
what = I("Use of pairlists in map functions"),
what = I("Use of pairlists in purrr functions"),
details = "Please coerce explicitly with `as.list()`",
user_env = user_env
)
Expand All @@ -138,7 +134,7 @@ vctrs_vec_compat <- function(x, user_env) {
} else if (is_call(x) || is.expression(x)) {
lifecycle::deprecate_soft(
when = "1.0.0",
what = I("Use of calls and pairlists in map functions"),
what = I("Use of calls and expressions in purrr functions"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe pairlists was a typo here

We now use vctrs_vec_compat() in every(), some(), and none() for consistency with map() and friends. That requires tweaking this message a little bit, but I think it is fine and unlikely to be seen by many people anyways.

details = "Please coerce explicitly with `as.list()`",
user_env = user_env
)
Expand Down
44 changes: 25 additions & 19 deletions revdep/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# Revdeps

## Failed to check (24)
## Failed to check (31)

|package |version |error |warning |note |
|:----------------|:-------|:------|:-------|:----|
|apa |? | | | |
|arealDB |0.9.4 |1 | | |
|ClusterGVis |? | | | |
|dsTidyverse |? | | | |
|eye |? | | | |
|ggmosaic |0.3.3 |1 | | |
|heplots |? | | | |
|hmde |? | | | |
|httk |? | | | |
|immcp |? | | | |
|imt |? | | | |
|intervalpsych |? | | | |
|irtQ |? | | | |
|isotracer |? | | | |
|jpcity |? | | | |
|[kerastuneR](failures.md#kerastuner)|0.1.0.7 |__+1__ | | |
|lcsm |? | | | |
|metajam |0.3.1 |1 | | |
Expand All @@ -18,28 +27,25 @@
|numbat |? | | | |
|ontologics |0.7.4 |1 | | |
|rdflib |0.2.9 |1 | | |
|rmweather |? | | | |
|rstanemax |? | | | |
|RVA |? | | | |
|sampler |? | | | |
|sbm |? | | | |
|SCpubr |? | | | |
|sprtt |? | | | |
|ssdGSA |? | | | |
|[stoRy](failures.md#story)|0.2.2 |__+1__ | | |
|Surrogate |? | | | |
|tidybins |? | | | |
|tidycomm |? | | | |
|[tidyjson](failures.md#tidyjson)|0.3.2 |__+1__ | |-1 |
|TriDimRegression |1.0.2 |1 | | |

## New problems (9)
## New problems (8)

|package |version |error |warning |note |
|:--------------|:-------|:--------|:-------|:----|
|[autothresholdr](problems.md#autothresholdr)|1.4.2 |__+1__ | |1 |
|[casino](problems.md#casino)|0.1.0 |__+1__ | |2 |
|[CPAT](problems.md#cpat)|0.1.0 |__+1__ | |1 |
|[egor](problems.md#egor)|1.24.2 |__+2__ | | |
|[immunarch](problems.md#immunarch)|0.9.1 |__+1__ | |1 |
|[moranajp](problems.md#moranajp)|0.9.7 |__+1__ | | |
|[quincunx](problems.md#quincunx)|0.1.10 |__+2__ | | |
|[SCORPIUS](problems.md#scorpius)|1.0.9 | |__+1__ |1 |
|[tfrmt](problems.md#tfrmt)|0.2.0 |1 __+1__ | | |
|package |version |error |warning |note |
|:---------|:-------|:------|:-------|:--------|
|[casino](problems.md#casino)|0.1.0 |__+1__ | |2 |
|[CPAT](problems.md#cpat)|0.1.0 |__+1__ | |1 |
|[egor](problems.md#egor)|1.24.2 |__+2__ | | |
|[immunarch](problems.md#immunarch)|0.9.1 |__+1__ | |1 |
|[meta](problems.md#meta)|8.2-1 | | |1 __+1__ |
|[moranajp](problems.md#moranajp)|0.9.7 |__+1__ | | |
|[quincunx](problems.md#quincunx)|0.1.10 |__+2__ | | |
|[SCORPIUS](problems.md#scorpius)|1.0.9 | |__+1__ |1 |

33 changes: 18 additions & 15 deletions revdep/cran.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
## revdepcheck results

We checked 2125 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package.
We checked 1702 reverse dependencies (1701 from CRAN + 1 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package.

* We saw 9 new problems
* We failed to check 24 packages
* We saw 8 new problems
* We failed to check 30 packages

Issues with CRAN packages are summarised below.

### New problems
(This reports the first line of each new failure)

* autothresholdr
checking re-building of vignette outputs ... ERROR

* casino
checking re-building of vignette outputs ... ERROR

Expand All @@ -26,6 +23,9 @@ Issues with CRAN packages are summarised below.
* immunarch
checking examples ... ERROR

* meta
checking installed package size ... NOTE

* moranajp
checking examples ... ERROR

Expand All @@ -36,17 +36,22 @@ Issues with CRAN packages are summarised below.
* SCORPIUS
checking whether package ‘SCORPIUS’ can be installed ... WARNING

* tfrmt
checking examples ... ERROR

### Failed to check

* apa (NA)
* arealDB (NA)
* ClusterGVis (NA)
* dsTidyverse (NA)
* ggmosaic (NA)
* heplots (NA)
* hmde (NA)
* httk (NA)
* immcp (NA)
* imt (NA)
* intervalpsych (NA)
* irtQ (NA)
* isotracer (NA)
* jpcity (NA)
* kerastuneR (NA)
* lcsm (NA)
* metajam (NA)
Expand All @@ -55,13 +60,11 @@ Issues with CRAN packages are summarised below.
* numbat (NA)
* ontologics (NA)
* rdflib (NA)
* rmweather (NA)
* rstanemax (NA)
* RVA (NA)
* sampler (NA)
* sbm (NA)
* SCpubr (NA)
* sprtt (NA)
* ssdGSA (NA)
* stoRy (NA)
* Surrogate (NA)
* tidybins (NA)
* tidycomm (NA)
* tidyjson (NA)
* TriDimRegression (NA)
Loading