r - 将向量传递到 all() 以测试相等性

标签 r dplyr purrr magrittr

我正在尝试将向量通过管道传递到 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 的单个管道中执行此操作。

如果 vectibble,则以下工作:

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

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

这也不符合我的目的,为了我自己的理解,我想知道为什么我的第一次尝试不起作用。

最佳答案

管道的工作方式是获取管道运算符的左侧并将其作为第一个参数传递给右侧函数。所以在这里,在这种情况下,因为我们需要将数据参数修改为 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

Warning message: In all(., . %in% c("a", "b")) : coercing argument of type 'character' to logical

这里发生的是

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

返回相同的消息。

为避免这种情况,我们使用 {}

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

这给了我们预期的答案。

关于r - 将向量传递到 all() 以测试相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60106626/

相关文章:

r - 使用 R 从多个顺序下拉菜单中抓取数据

R max 函数在 'dplyr' 内使用时返回伪值

r - 将多个模型公式应用于数据组

r - 如果单元格包含特定字符串,则复制相邻单元格的字符串

R 将竞争模型拟合到 dplyr/tidyr/broom 框架内的嵌套数据

r - 如何在R中不使用循环快速访问列表列表中的元素? (Googleway 套餐)

r - 失败时如何打印函数的参数?

r - 在 Google Colab 中永久安装 R 包

r - 在 as.numeric() 中避免 NA

r - 使用 rep 和 seq 但没有 c() 函数生成向量