Set comprehension with the magrittr Pipe. Always use the basic syntax:

.x %>% that_for_all(.y) %>% we_have_*(f(.x, .y)), but see the examples for more detail.

that_for_all(.x, .y)

that_for_any(.x, .y)

we_have(that_for, formula, result = "vector")

Arguments

.x

A set, represented as either an atomic vector or a list

.y

A set to compare to .x

that_for

A list passed to we_have()—can be ignored with proper syntax

formula

A function, lambda, or formula. Must be understood by rlang::as_function()

result

Should the expression return a vector or an Iterator?

Value

For that_for_all() and that_for_any(), an object of S3 class that_for_all or that_for_any. For we_have(), a vector of the same type as .x if return == 'vector' and an Iterator object if return == 'Iterator'.

Details

formula can be anything that is recognized as a function by rlang::as_function(). See the examples for how to specify the end of a sequence when used with an Iterator.

Handling missing values in these expressions is possible and sometimes desirable but potentially painful because NA values can't be compared with normal operators. See the README for a detailed example.

Note that .x %>% that_for_all(.y) is vacuously true if .y is empty, while .x %>% that_for_any(.y) is vacuously false if .y is empty.

Note

if .y is an numeric vector, you probably want a value obtained from range(start, end) rather than start:end or seq.int(start,end), as when start is greater than end you want an empty vector rather than counting backwards. Note that range() views end as a supremum, not a maximum, thus range(a,b) is equivalent to the set [a,b) when a < b or the empty set when b >= a.

Also note that there is some indirection in the way that .x and .y are referenced in the formula. In the function we_have(), the actual name of the two sets is .x and .y. That is what makes the function interface work, e.g. function(.x, .y) .x - .y. On the other hand, purrr-style lambda expressions, e.g. ~.x - .y, use positional arguments, where .x is the first argument and .y is the second argument, no matter their names. Because those are actually their names, this difference should never matter.

See also

The implementation of these functions involves code adapted from purrr::every() and purrr::some(), by Lionel Henry, Hadley Wickham, and RStudio, available under the MIT license.

Examples

2:100 %>% that_for_all(range(2, .x)) %>% we_have(function(.x, .y) .x %% .y != 0) #is the same as
#> [1] 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
2:100 %>% that_for_all(range(2, .x)) %>% we_have(~.x %% .y) # 0 = F, (not 0) = T
#> [1] 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
#c.f. primes <- 2:100 %>% that_for_all(range(2, .x)) %>% we_have(~.x %% .y, "Iterator") yield_next(primes)
#> [1] 2
primes2 <- clone(primes) # Refer to the vector .x with `.x_vector` and the current index of that vector with `.i` # For example, to yield to the end of the sequence: yield_while(primes, .x_vector[.i] <= length(.x_vector))
#> (Note: result has reached end of sequence)
#> [1] 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
# `.finished` is an alias for `.x_vector[.i] > length(.x_vector)` # Equivalent to previous expression: yield_while(primes2, !.finished)
#> (Note: result has reached end of sequence)
#> [1] 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
{c("I", "Don't", "wan't", "chicken") %>% that_for_all("\'") %>% we_have(~grepl(.y, .x))}
#> [1] "Don't" "wan't"
#Twin primes 1 through 100 primes <- 2:100 %>% that_for_all(range(2, .x)) %>% we_have(~.x %% .y) primes %>% that_for_any(primes) %>% we_have(~abs(.x - .y) == 2)
#> [1] 3 5 7 11 13 17 19 29 31 41 43 59 61 71 73
#Prime numbers 1 through 100 that are two away from a square number (2:100 %>% that_for_all(range(2, .x)) %>% we_have(~.x %% .y)) %>% that_for_any(range(2, .x)) %>% we_have(~sqrt(.x + 2) == .y | sqrt(.x - 2) == .y)
#> [1] 7 11 23 47 79 83