los*_*ost 1 r dplyr magrittr purrr
我正在尝试将向量通过管道传输到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'
Run Code Online (Sandbox Code Playgroud)
如果我之前打破管道all()并将输出分配给一个 object p,然后作为第二个命令传递p给all()它,它工作正常:
vec %>%
keep(!grepl("b", .)) -> p
all(p == "a")
#> [1] TRUE
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这有效,而我的第一次尝试却没有。我希望能够在导致TRUE.
如果vec改为 atibble以下工作:
vec <- tibble(var = c("a", "b", "a"))
vec %>%
filter(!grepl("b", var)) %$%
all(.$var == "a")
#> [1] TRUE
Run Code Online (Sandbox Code Playgroud)
这也不符合我的目的,我想知道为什么我的第一次尝试不起作用。
pipe 的工作方式是将 pipe 运算符的左侧作为第一个参数传递给右侧函数。所以在这里,在这种情况下,由于我们需要将 data 参数修改为all,我们需要阻止管道将 LHS 传递到 RHS。我们可以通过使用来做到这一点{}。
library(magrittr)
vec %>% purrr::keep(!grepl("b", .)) %>% {all(. == 'a')}
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)
在 中vec,让我们检查所有元素是否都是"a"“ b”。我们可以%in%在这里使用。
vec <- c("a", "b", "a")
Run Code Online (Sandbox Code Playgroud)
没有管道的普通版本是:
all(vec %in% c('a', 'b'))
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)
使用管道,如果我们尝试
vec %>% all(. %in% c('a', 'b'))
Run Code Online (Sandbox Code Playgroud)
我们得到
#[1] NA
Run Code Online (Sandbox Code Playgroud)
警告消息:在 all(., . %in% c("a", "b")) 中:将“字符”类型的参数强制转换为逻辑
这里发生的事情是
all(vec, vec %in% c('a', 'b'))
#[1] NA
Run Code Online (Sandbox Code Playgroud)
警告消息:在 all(vec, vec %in% c("a", "b")) 中:将“字符”类型的参数强制转换为逻辑
返回相同的消息。
为了避免这种情况,我们使用 {}
vec %>% {all(. %in% c('a', 'b'))}
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)
这给了我们预期的答案。
| 归档时间: |
|
| 查看次数: |
267 次 |
| 最近记录: |