Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement vec_pany() and vec_pall() #1675

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,8 @@ export(vec_math_base)
export(vec_names)
export(vec_names2)
export(vec_order)
export(vec_pall)
export(vec_pany)
export(vec_proxy)
export(vec_proxy_compare)
export(vec_proxy_equal)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# vctrs (development version)

* New `vec_pany()` and `vec_pall()` parallel variants of `any()` and `all()`
(in the same way that `pmin()` and `pmax()` are parallel variants of `min()`
and `max()`) (#1675).

* `vec_c(outer = c(inner = 1))` now produces correct error messages (#522).

* If a data frame is returned as the proxy from `vec_proxy_equal()`,
Expand Down
57 changes: 57 additions & 0 deletions R/parallel.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#' Parallel `any()` and `all()`
#'
#' @description
#' These functions are variants of [any()] and [all()] that work in parallel on
#' multiple inputs at once. They work similarly to how [pmin()] and [pmax()] are
#' parallel variants of [min()] and [max()].
#'
#' @details
#' `vec_pany()` and `vec_pall()` are consistent with [any()] and [all()] when
#' there are no inputs to process in parallel:
#'
#' - `any()` returns `FALSE` with no inputs. Similarly, `vec_pany(.size = 1)`
#' and `vec_pany(NA, .na_rm = TRUE)` both return `FALSE`.
#'
#' - `all()` returns `TRUE` with no inputs. Similarly, `vec_pall(.size = 1)`
#' and `vec_pall(NA, .na_rm = TRUE)` both return `TRUE`.
#'
#' @param ... Logical vectors. These will be [recycled][vector_recycling_rules]
#' to their common size.
#'
#' @param .na_rm Should missing values be removed?
#'
#' @param .size An optional output size that overrides the common size of the
#' inputs in `...`.
#'
#' @name parallel-operators
#'
#' @examples
#' x <- c(TRUE, FALSE, NA, TRUE, NA)
#' y <- c(FALSE, FALSE, TRUE, TRUE, NA)
#'
#' vec_pany(x, y)
#' vec_pall(x, y)
#'
#' # Missing values can be removed from the computation
#' vec_pany(x, y, .na_rm = TRUE)
#' vec_pall(x, y, .na_rm = TRUE)
#'
#' # Same empty behavior as `any()` and `all()`
#' vec_pany(.size = 1)
#' any()
#'
#' vec_pall(.size = 1)
#' all()
NULL

#' @rdname parallel-operators
#' @export
vec_pany <- function(..., .na_rm = FALSE, .size = NULL) {
.Call(ffi_vec_pany, list2(...), .na_rm, .size, environment())
}

#' @rdname parallel-operators
#' @export
vec_pall <- function(..., .na_rm = FALSE, .size = NULL) {
.Call(ffi_vec_pall, list2(...), .na_rm, .size, environment())
}
6 changes: 5 additions & 1 deletion _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ template:

includes:
in_header: |
<script defer data-domain="vctrs.r-lib.org,all.tidyverse.org" src="https://plausible.io/js/plausible.js"></script>
<script defer data-domain="vctrs.r-lib.org,all.tidyverse.org" src="https://plausible.io/js/plausible.js"></script>

reference:
- title: User FAQ
Expand Down Expand Up @@ -93,6 +93,10 @@ reference:
- vec_seq_along
- vec_identify_runs

- title: Reducers
contents:
- vec_pall

- title: New classes
contents:
- list_of
Expand Down
54 changes: 54 additions & 0 deletions man/parallel-operators.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions src/decl/parallel-decl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
static inline
r_obj* ffi_vec_p(r_obj* xs,
r_obj* ffi_na_rm,
r_obj* ffi_size,
r_obj* frame,
enum vctrs_parallel parallel);

static
r_obj* vec_p(r_obj* xs,
bool na_rm,
r_ssize size,
enum vctrs_parallel parallel,
struct r_lazy call);

static inline
void vec_pall_init(const int* v_x, bool na_rm, r_ssize size, int* v_out);
static inline
void vec_pany_init(const int* v_x, bool na_rm, r_ssize size, int* v_out);

static inline
void vec_pall_fill(const int* v_x, bool na_rm, r_ssize size, int* v_out);
static inline
void vec_pany_fill(const int* v_x, bool na_rm, r_ssize size, int* v_out);

static inline
void vec_pall_init_na_rm(const int* v_x, r_ssize size, int* v_out);
static inline
void vec_pall_fill_na_rm(const int* v_x, r_ssize size, int* v_out);

static inline
void vec_pany_init_na_rm(const int* v_x, r_ssize size, int* v_out);
static inline
void vec_pany_fill_na_rm(const int* v_x, r_ssize size, int* v_out);

static inline
void vec_pall_init_na_keep(const int* v_x, r_ssize size, int* v_out);
static inline
void vec_pall_fill_na_keep(const int* v_x, r_ssize size, int* v_out);

static inline
void vec_pany_init_na_keep(const int* v_x, r_ssize size, int* v_out);
static inline
void vec_pany_fill_na_keep(const int* v_x, r_ssize size, int* v_out);
4 changes: 4 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ extern r_obj* ffi_list_all_vectors(r_obj*, r_obj*);
extern r_obj* ffi_list_check_all_vectors(r_obj*, r_obj*);
extern r_obj* ffi_as_short_length(r_obj*, r_obj*);
extern r_obj* ffi_s3_get_method(r_obj*, r_obj*, r_obj*);
extern r_obj* ffi_vec_pall(r_obj*, r_obj*, r_obj*, r_obj*);
extern r_obj* ffi_vec_pany(r_obj*, r_obj*, r_obj*, r_obj*);


// Maturing
Expand Down Expand Up @@ -321,6 +323,8 @@ static const R_CallMethodDef CallEntries[] = {
{"ffi_list_check_all_vectors", (DL_FUNC) &ffi_list_check_all_vectors, 2},
{"ffi_as_short_length", (DL_FUNC) &ffi_as_short_length, 2},
{"ffi_s3_get_method", (DL_FUNC) &ffi_s3_get_method, 3},
{"ffi_vec_pall", (DL_FUNC) &ffi_vec_pall, 4},
{"ffi_vec_pany", (DL_FUNC) &ffi_vec_pany, 4},
{"ffi_exp_vec_cast", (DL_FUNC) &exp_vec_cast, 2},
{NULL, NULL, 0}
};
Expand Down
Loading