使用未评估的参数创建未评估的函数调用 [英] Creating an unevaluated function call with unevaluated arguments

查看:73
本文介绍了使用未评估的参数创建未评估的函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们直接在R中调用一个函数,则会发生惰性求值,因此只有在函数体中遇到函数参数时,才对函数参数求值.这样的效果是,在函数的开头使用match.call(),例如lm之类的模型拟合器,将使用未评估的函数参数捕获调用.因此,通过执行模型拟合函数,可以使用promise而不是评估的参数来检索对函数的调用.这样做的缺点是必须先执行该函数,然后才能获得带有未评估参数的调用.

If we call a function directly in R, lazy evaluation takes place, so that the function arguments are not evaluated until they are encountered in the function body. An effect of this is that using match.call() at the beginning of a function, say a model fitter like lm, captures the call with unevaluated function arguments. Thus, the call to the function can be retrieved with promises instead of evaluated arguments by executing the model fitting function. The disadvantage of this is that the function has to be executed before the call with unevaluated arguments can be obtained.

R的call函数可用于创建对模型拟合函数的未评估调用,但会评估指定的参数.我想做的是创建一个对象,该对象是对函数的未评估调用,其中函数参数也未评估.一个相当琐碎的示例(假设arg1 + arg2部分是在计算上昂贵的东西):

R's call function, on the other hand, can be used to create an unevaluated call to a model fitting function, but the specified arguments are evaluated. What I would like to do is to create an object that is an unevaluated call to a function in which the function arguments are also unevaluated. A rather trivial example (pretend that the arg1 + arg2-part is something which is computationally expensive):

Foo <- function(arg1, arg2){
 mycall <- match.call()
 value <- arg1 + arg2
 list(value = value,
      call = mycall)
}

x <- 1
y <- 2

# calling Foo directly
test1 <- Foo(x,y)
test1   # the call with unevaluated arguments is now accessible, but the 
        # computations in Foo had to be performed as well.

# now via 'call'
Foocall <- call("Foo", arg1 = x, arg2 = y)
test2 <- eval(Foocall)
test2
Foocall # Foocall is an unevaluated call to Foo, but arg1 and arg2 in 
        # Foocall are no longer promises.   

我想要的是这样的

Foocall <- call("Foo", arg1 = x, arg2 = y, eval.dots = FALSE)

屈服

 # not run 
 > Foocall
 > Foo(arg1 = x, arg2 = y)

我的问题有简单的解决方法吗?

Is there an easy solution to my problem?

推荐答案

使用提供的quote()调用包装每个提供的参数将完成您似乎想要的事情:

Wrapping each supplied argument with a call to quote() will accomplish what you seem to be asking for:

Foocall <- call("Foo", arg1=quote(x), arg2=quote(y))

## Check that it works
Foocall
# Foo(arg1 = x, arg2 = y)

eval(Foocall)
# $value
# [1] 3
# 
# $call
# Foo(arg1 = x, arg2 = y)

identical(Foocall, eval(Foocall)$call)
# [1] TRUE

如果您进一步希望能够提供未命名的参数,并使它们按位置自动匹配其关联的形式参数,则只需将前面的内容包装在对match.call()的调用中即可:

If you'd further like to be able to supply unnamed arguments and have them automatically matched by position to their associated formal arguments, just wrap the preceding in a call to match.call():

## Note that arg1 and arg2 not explicitly mentioned anywhere in this call
match.call(Foo, call("Foo", quote(x), quote(y))) 
# Foo(arg1 = x, arg2 = y)

这篇关于使用未评估的参数创建未评估的函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆