R基管不能用反引号引用吗?找不到函数“|>”

问题描述 投票:0回答:1

我正在尝试在基管周围构建一个包装器

|>
,对左侧进行一些修改,然后正常通过管道向前传输。在研究此问题时,我发现与其他操作员相比,基管具有以下特点:

按预期工作:

`+`(1,2)
#> [1] 3

`<-`("foo", 1)
foo
#> [1] 1

library(magrittr)
`%>%`(1, print)
#> [1] 1

未按预期工作:

`|>`(1, print)
#> Error in `|>`(1, print): could not find function "|>"

这意味着,例如,虽然以下内容适用于

magrittr
管道

as.call(c(as.name("%>%"), "foo", substitute(print)))
#> "foo" %>% print

并且可以传递给

eval()
:

eval(as.call(c(as.name("%>%"), "foo", substitute(print))))
#> [1] "foo"

它不适用于基管:

eval(as.call(c(as.name("|>"), "foo", substitute(print))))
#> Error in `|>`("foo", print): could not find function "|>"

我一直在努力寻找这方面的文档,因为我不太确定如何描述这个问题,而且谷歌通常不能很好地处理涉及特殊字符的查询,即使是在引号中。

编辑:有关上下文的更多详细信息

作为一个玩具示例,假设我们想要制作一个管道变体,通过管道传输对象的名称,而不是对象,并且不改变我们的用法:

library(magrittr)
`%>>%` <- function(lhs, rhs) {
  # get lhs as a character
  lhs.name <- deparse(substitute(lhs))
  
  # the parent environment
  parent <- parent.frame()
  
  # the environment in which to evaluate pipeline
  env <- new.env(parent = parent)
  
  # magrittr version
  eval(
    as.call(c(as.name("%>%"), lhs.name, substitute(rhs))),
    env, env
  )
}

foo_func <- function(arg1, arg2, arg3) {
  print(arg1)
  print(arg2)
  print(arg3)
  arg2 + arg3
}

thing %>>% foo_func(2,4)
#> [1] "thing"
#> [1] 2
#> [1] 4
#> [1] 6

为了避免

magrittr
依赖性,我有兴趣使用
|>
而不是
%>%
来完成这项工作。看来我们可以替换为

eval(
    str2lang(paste0("'", lhs.name, "'", " |> ", deparse(substitute(rhs)))), 
    env, env
  ) 

虽然我还没有彻底测试过。

r pipe eval magrittr
1个回答
0
投票

如果问题是如何在没有依赖关系的情况下实现“%>>%”,则从 poorman 源代码复制

insert_dot
源代码 https://github.com/nathaneastwood/poorman/blob/master/R/pipe.R 并将同一页面的
%>%
源码修改为:

"%>>%" <- function(lhs, rhs) {
  rhs_call <- insert_dot(substitute(rhs))
  eval(rhs_call, envir = list(`.` = substitute(lhs)), enclos = parent.frame())
}

# tests

if (exists("xyz")) rm(xyz)

xyz %>>% paste0("*")
## [1] "xyz*"

xyz %>>% paste(., .)
## [1] "xyz xyz"
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.