добавление вектора в all () для проверки равенства - PullRequest
0 голосов
/ 07 февраля 2020

Я пытаюсь передать вектор в оператор all(), чтобы проверить, все ли элементы равны определенному значению. Я полагаю, что мне нужно использовать канал экспозиции %$%, поскольку all() не имеет встроенного аргумента данных. Моя попытка приводит к ошибке:

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'

Если я разорву трубу до all() и назначу выход для объекта p, а затем передам p в all() в качестве второй команды все работает нормально:

vec %>%
  keep(!grepl("b", .)) -> p

all(p == "a")
#> [1] TRUE

Я не понимаю, почему это работает, а моя первая попытка - нет. Я хотел бы быть в состоянии сделать это в одной трубе, которая приводит к TRUE.

Если vec вместо tibble, то следующие работы:

vec <- tibble(var = c("a", "b", "a"))

vec %>%
  filter(!grepl("b", var)) %$%
  all(.$var == "a")
#> [1] TRUE

Это также не подходит для моих целей, и я бы понял, почему моя первая попытка не работает.

1 Ответ

6 голосов
/ 07 февраля 2020

Способ работы pipe заключается в том, что он принимает левую часть оператора pipe и передает его в качестве первого аргумента в правую функцию. Итак, здесь, в этом случае, когда нам нужно изменить аргумент данных на all, нам нужно запретить каналу передавать LHS в RHS. Мы можем сделать это, используя {}.

library(magrittr)

vec %>% purrr::keep(!grepl("b", .)) %>% {all(. == 'a')}
#[1] TRUE

В vec давайте проверим, все ли элементы "a" или "b". Мы можем использовать %in% здесь.

vec <- c("a", "b", "a")

Обычная версия без труб будет:

all(vec %in% c('a', 'b'))
#[1] TRUE

С трубами, если мы попробуем

vec %>% all(. %in% c('a', 'b'))

Получим

#[1] NA

Предупреждающее сообщение: Всего (.,.% В% c ("a", "b")): приведение аргумента типа 'символ' к логическому

что здесь происходит следующее:

all(vec, vec %in% c('a', 'b'))
#[1] NA

Предупреждающее сообщение: In all (ve c, ve c% в% c ("a", "b")): принудительный аргумент введите «символ» в логический

, который возвращает то же сообщение.

Чтобы избежать этого, мы используем {}

vec %>% {all(. %in% c('a', 'b'))}
#[1] TRUE

, который дает нам ожидаемый ответ.

...