2014-03-13 64 views
1

如果我們直接R中調用一個函數,懶惰的評價發生,使函數參數不計算,直到它們在函數體中遇到。這樣做的一個效果是在函數的開頭使用match.call()(比如lm這樣的模型修正器)會使用未經評估的函數參數捕獲該調用。因此,通過執行模型擬合函數,可以用promise來取代對函數的調用,而不是通過評估參數。這樣做的缺點是函數必須在未獲取參數的調用之前執行。創建未計算的函數調用未評估的參數

另一方面,函數R的call可用於創建對模型擬合函數的未評估調用,但會評估指定的參數。我想要做的是創建一個對未調用的函數的對象,該函數中函數參數也是未評估的。一個相當簡單的例子(假裝arg1 + arg2 -part是一些東西,是計算成本):

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) 

有沒有一個簡單的解決我的問題?

+0

如果我理解正確的你,當你調用Foocall你想'美孚(ARG1 = X,ARG2 = Y)(型)'那是未評估的x和y? – infominer

回答

2

包裝紙一起quote()電話每次提供的參數將完成你彷彿要詢問:

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()

## 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) 
+0

我喜歡使用相同的檢查。 – infominer

+0

是的,這似乎工作。在過去,我曾嘗試使用'substitute'而不是'quote',但在更復雜的設置中,替換有時會失敗。從來沒有真正想過報價,謝謝! –