r - 捕获用于 S3 调度的参数表达式
问题描述
我遇到了 rlang 和 base 之间出乎意料的行为分歧。正如这句话所证明的那样,显然存在差异。这是从 0.4.1 开始的,但类似的语言仍在 0.4.2 中,现在指代enquo
。
就基本函数而言,enexpr(arg) 对应于 base::substitute(arg)(尽管该函数还具有复杂的替换语义)
- 任何人都可以使用具有的 rlang 函数来匹配行为
substitute()
吗? - 有没有很好的解释为什么
enexpr()
不起作用?我猜是因为它与 S3 方法调度有关。 - 我特别感兴趣如何使用 rlang 来做到这一点,我已经可以使用 base 来实现我想要的行为。
我的例子是无稽之谈,但它强调的是我无法捕获df
作为第一个参数传入通用 S3 函数的表达式(在本例中为单个符号,)。
library(rlang)
f <- function(obj) {
enexpr(obj)
}
print(f(print("hello")))
#> print("hello")
# behavior matches expectations
df <- data.frame(a = 1:5, b = letters[1:5])
class(df) <- c("custom", class(df))
`[.custom` <- function(x, i) {
call2(expr(`[`), enexpr(x), i)
}
df[4]
#> list(a = 1:5, b = 1:5)[4]
sloop::s3_dispatch(df[4])
#> => [.custom
#> * [.data.frame
#> [.default
#> * [ (internal)
# It's dispatching as expected, but I don't get
# `df[4]` back as a call.
df <- data.frame(a = 1:5, b = letters[1:5])
class(df) <- c("custom", class(df))
`[.custom` <- function(x, i) {
call2(expr(`[`),substitute(x), i)
}
df[4]
#> df[4]
# substitute works
packageVersion("rlang")
#> [1] '0.4.2'
# Created on 2019-12-05 by the reprex package (v0.3.0)
解决方案
这是一个记录在案的问题,rlang
并且可能会在未来的版本中添加支持。
当前的解决方法是在调度时引入另一个级别的引用:
`[` <- function(x, i) {
ex <- eval_tidy( enquo(x) )
UseMethod('[', ex)
}
`[.custom` <- function(x, i)
call2(expr(`[`), enexpr(x), i)
df[4]
# df[4]
推荐阅读
- cakephp-2.3 - 如何生成类别树,显示技术详细信息表中的相应评级
- javascript - 如何使用 jquery 在 laravel 中单击下拉菜单中获取 li 的值?
- php - 使代码更小的可能性
- angularjs - 将 angularJS 值发送到 MVC 操作
- angular - 角材料2不起作用
- html - Youtube iframe src 自动播放在 Chrome 浏览器中不起作用
- php - 我的简单搜索引擎有问题
- apache-spark - Spark:在每个分区中变得不同
- ios - JusPayExpress 结帐错误 - JSURLNotPassed (102)
- html - 清理 htaccess 文件以指示 cPanel 中的重定向