问题
I'm trying to pipe a vector into an all()
statement to check if all elements are equal to a certain value. I figure I need to use the exposition pipe %$%
since all()
does not have a built-in data argument. My attempt leads to an error:
library(tidyverse)
library(magrittr)
vec <- c("a", "b", "a")
vec %>%
keep(!grepl("b", .)) %$%
all(. == "a")
#> Error in eval(substitute(expr), data, enclos = parent.frame()): invalid 'envir' argument of type 'character'
If I break the pipe before all()
and assign the output to an object p
, and then pass p
to all()
as a second command it works fine:
vec %>%
keep(!grepl("b", .)) -> p
all(p == "a")
#> [1] TRUE
I don't understand why this works while my first attempt does not. I'd like to be able to do this in a single pipe that results in TRUE
.
If vec
is instead a tibble
the following works:
vec <- tibble(var = c("a", "b", "a"))
vec %>%
filter(!grepl("b", var)) %$%
all(.$var == "a")
#> [1] TRUE
This doesn't suit my purposes as well, and I'd for my own understanding to know why my first attempt does not work.
回答1:
The way pipe works is it takes the left-hand side of the pipe operator and passes it as a first argument to the right hand side function. So here, in this case as we need to modify the data argument to all
, we need to stop pipe from passing the LHS to the RHS. We can do that by using {}
.
library(magrittr)
vec %>% purrr::keep(!grepl("b", .)) %>% {all(. == 'a')}
#[1] TRUE
In vec
, let's check if all the elements are either "a"
or "b
". We can use %in%
here.
vec <- c("a", "b", "a")
Plain version without pipes would be :
all(vec %in% c('a', 'b'))
#[1] TRUE
With pipes, if we try
vec %>% all(. %in% c('a', 'b'))
We get
#[1] NA
Warning message: In all(., . %in% c("a", "b")) : coercing argument of type 'character' to logical
what is happening here is
all(vec, vec %in% c('a', 'b'))
#[1] NA
Warning message: In all(vec, vec %in% c("a", "b")) : coercing argument of type 'character' to logical
which returns the same message.
To avoid this we use {}
vec %>% {all(. %in% c('a', 'b'))}
#[1] TRUE
which gives us the expected answer.
来源:https://stackoverflow.com/questions/60106626/piping-a-vector-into-all-to-test-equality