r - 在传递给函数之前展开存储在变量中的调用

标签 r function

我有一个存储在变量中的调用。如果相关的话,该调用源自一个片面的公式:

f <- ~ a + b
rhs <- rlang::f_rhs(f)
rhs
#> a + b

reprex package于2020年3月19日创建(v0.3.0)

现在,公式可能包含 bquote 式转义 .(),我想获取所有转义名称。

查看bquote的源代码,我创建了这个函数:

escapedNames <- function (expr, where = parent.frame()) 
{
    unquote <- function(e) {
        if (is.pairlist(e)) {
            NULL
        } else if (length(e) <= 1L) {
             NULL
        } else if (e[[1L]] == as.name(".")) {
            deparse(e[[2L]])
        } else {
            x <- sapply(e, unquote)
            unlist(x)
        }
    }
    unquote(substitute(expr))
}

escapedNames(a + .(b) + c)
#> [1] "b"

正如您所看到的,它对于硬编码表达式来说效果很好。但是,我不知道如何传递存储在变量中的调用。

f <- ~ a + .(b)
rhs <- rlang::f_rhs(f)
escapedNames(rhs)
#> NULL

当然,这是完全有道理的,因为escapedNames将它给出的任何内容视为我想要分析的调用,所以它不知道在之前扩展rhs寻找名字。

那么,我该如何解决这个问题呢?

最佳答案

在发布赏金后,我立即想到了一种方法,但请告诉我更好的方法!

我们可以使用evalrlang::expr在计算escapedNames之前强制扩展公式变量:

escapedNames <- function (expr) 
{
    unquote <- function(e) {
        if (is.pairlist(e) || length(e) <= 1L) NULL
        else if (e[[1L]] == as.name("."))      deparse(e[[2L]])
        else                                   unlist(sapply(e, unquote))
    }
    unquote(substitute(expr))
}

formula <- ~ a + .(b) + c + .(d)
rhs <- rlang::f_rhs(formula)

eval(rlang::expr(escapedNames(!!rhs)))
#> [1] "b" "d"

reprex package于2020年3月23日创建(v0.3.0)

关于r - 在传递给函数之前展开存储在变量中的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60762048/

相关文章:

html - R 中的 cox 回归输出表或图

r - 如何在R中绘制下图?这些类型的图表叫什么?

javascript - 单击功能,窗口高度在加载和调整大小时可变

javascript - 简单的 Javascript 数学函数 - 加法/不起作用?

php - RGB 到最接近的预定义颜色

math - 绘制2D隐式标量场的等值线

javascript - Shiny 的模态窗口不接受 js 和 css

在顶部使用时减少行间距

r - all.equal 函数给出了误报

.net - 封装无参数有返回值的方法