从函数调用时,有没有办法使 match.call + eval 组合起作用?
Is there a way to make match.call + eval combination work when called from a function?
我使用的包有 2 个函数,最终如下所示:
pkgFun1 <- function(group) {
call <- match.call()
pkgFun2(call)
}
pkgFun2 <- function(call) {
eval(call$group)
}
如果我只调用 pkgFun1(group = 2)
,它工作正常。但我想从一个函数中调用它:
myFun <- function(x) {
pkgFun1(group = x)
}
myFun(x = 2)
## Error in eval(call$group) : object 'x' not found
如果我不能修改包函数,而只能修改myFun
,有什么办法可以避免这个错误?
有类似的问题,例如 or ,但我的特殊问题是我无法修改包含 eval
调用的代码部分。
是 pkgFun2 错了,所以我认为你运气不好,没有一些奇怪的扭曲。它需要将适当的环境传递给 eval();如果你不能修改它,那么你就不能修复它。
这个 hack 可能看起来有效,但在现实生活中却行不通:
pkgFun1 <- function(group) {
call <- match.call()
f <- pkgFun2
environment(f) <- parent.frame()
f(call)
}
这样,您调用的 pkgFun2
副本已修改,因此其环境适合评估调用。它在测试用例中有效,但将来会给您带来无尽的痛苦,因为 非本地 pkgFun2
中的所有内容 将在错误的位置进行搜索。例如,
myFun <- function(x) {
eval <- function(...) print("Gotcha!")
pkgFun1(group = x)
}
myFun(x = 2)
# [1] "Gotcha!"
最好修复 pkgFun2
。这是一个修复方法:
pkgFun1 <- function(group) {
call <- match.call()
pkgFun2(call, parent.frame())
}
pkgFun2 <- function(call, envir) {
eval(call$group, envir = envir)
}
编辑添加: 实际上,还有另一个不那么奇怪的 hack 应该适用于您原来的 pkgFun1
和 pkgFun2
。如果您强制 x
的计算发生在 myFun
中,以便 pkgFun1
永远不会看到表达式 x
,它应该可以工作。例如,
myFun <- function(x) {
do.call("pkgFun1", list(group = x))
}
如果你这样做,那么在 myFun(2)
之后,pkgFun1
变量 call
将是 pkgFun1(group = 2)
并且你不会得到关于 [=19= 的错误].
我使用的包有 2 个函数,最终如下所示:
pkgFun1 <- function(group) {
call <- match.call()
pkgFun2(call)
}
pkgFun2 <- function(call) {
eval(call$group)
}
如果我只调用 pkgFun1(group = 2)
,它工作正常。但我想从一个函数中调用它:
myFun <- function(x) {
pkgFun1(group = x)
}
myFun(x = 2)
## Error in eval(call$group) : object 'x' not found
如果我不能修改包函数,而只能修改myFun
,有什么办法可以避免这个错误?
有类似的问题,例如eval
调用的代码部分。
是 pkgFun2 错了,所以我认为你运气不好,没有一些奇怪的扭曲。它需要将适当的环境传递给 eval();如果你不能修改它,那么你就不能修复它。
这个 hack 可能看起来有效,但在现实生活中却行不通:
pkgFun1 <- function(group) {
call <- match.call()
f <- pkgFun2
environment(f) <- parent.frame()
f(call)
}
这样,您调用的 pkgFun2
副本已修改,因此其环境适合评估调用。它在测试用例中有效,但将来会给您带来无尽的痛苦,因为 非本地 pkgFun2
中的所有内容 将在错误的位置进行搜索。例如,
myFun <- function(x) {
eval <- function(...) print("Gotcha!")
pkgFun1(group = x)
}
myFun(x = 2)
# [1] "Gotcha!"
最好修复 pkgFun2
。这是一个修复方法:
pkgFun1 <- function(group) {
call <- match.call()
pkgFun2(call, parent.frame())
}
pkgFun2 <- function(call, envir) {
eval(call$group, envir = envir)
}
编辑添加: 实际上,还有另一个不那么奇怪的 hack 应该适用于您原来的 pkgFun1
和 pkgFun2
。如果您强制 x
的计算发生在 myFun
中,以便 pkgFun1
永远不会看到表达式 x
,它应该可以工作。例如,
myFun <- function(x) {
do.call("pkgFun1", list(group = x))
}
如果你这样做,那么在 myFun(2)
之后,pkgFun1
变量 call
将是 pkgFun1(group = 2)
并且你不会得到关于 [=19= 的错误].