How to write any(diff(vec) < 0) as a pipe?

88 Views Asked by At

I have a vector vec like this vec <- c(1,4,5) and I want to check whether there are any steps down in the vector. I do this using:

any(diff(vec) < 0)
# [1] FALSE

No steps down. Okay. But when I try to use this code in a pipe I get a TRUE and an warning:

library(magrittr)
vec %>% diff() %>% any(. < 0)
# [1] TRUE
# Warning message:
# In any(., . < 0) : coercing argument of type 'double' to logical

How to correctly write any(diff(vec) < 0) as a pipe?

4

There are 4 best solutions below

2
user2554330 On BEST ANSWER

You have a couple of solutions already, but no explanation. The reason your original didn't work is that magrittr pipes treat . differently when it is in a nested function call.

By nested function call, I mean that . is not an argument to the function that is the target of the pipe. In any(. < 0), that function is any(), and its argument is . < 0, which is actually a function call to the < function. So the . is in a "nested function call".

If . is only in a nested function call, it is implicitly used as the first argument as well, so the code

x %>% any(. < 0)

is treated as

any(x, x < 0)

To suppress this weird behaviour, put the expression in braces, i.e. your example would be

vec %>% diff() %>% { any(. < 0) }
0
ThomasIsCoding On

You can try

vec %>%
    diff() %>%
    `<`(0) %>%
    any()

or

vec %>%
    diff() %>%
    {
        . < 0
    } %>%
    any()

or

vec %>%
    {
        any(diff(.) < 0)
    }
0
PGSA On

using magrittr pipes:

vec %>% diff() %>% `<`(0) %>% any()
[1] FALSE

Using base pipes:

vec |> diff() |> {\(x)x < 0}() |> any()
[1] FALSE

See here for more info: https://stackoverflow.com/a/72474832/16730940

2
jay.sf On

Base

vec |> diff() |> base::`<`(0) |> any()
# [1] FALSE

magrittr

library(magrittr)

vec %>% diff %>% `<`(0) %>% any
# [1] FALSE

or, as suggested by @MrFlick

library(magrittr)

vec %>% diff %>% is_less_than(0) %>% any
# [1] FALSE

Data:

vec <- c(1, 4, 5)