2017-07-25 19 views
1

我已閱讀其他答案,以解決與「承諾正在評估中」的警告有關的問題,但我無法看到它們如何幫助我避免這個問題。如何避免承諾已在評估警告中作爲另一個參數的函數設置默認參數

這裏我有一個函數,對於一個方法,採用一個默認的參數值,它是另一個值的函數。

myfun <- function(x, ones = NULL) { 
    UseMethod("myfun") 
} 


myfun.list <- function(x, ones = NA) { 
    data.frame(x = x[[1]], ones) 
} 

ones <- function(x) { 
    rep(1, length(x)) 
} 

到目前爲止,一切都很好:

myfun(list(letters[1:5])) 
## x ones 
## 1 a NA 
## 2 b NA 
## 3 c NA 
## 4 d NA 
## 5 e NA 

但是,當我定義設定了ones參數作爲函數ones(x)默認的另一種方法,我得到一個錯誤:

myfun.character <- function(x, ones = ones(x)) { 
    myfun(as.list(x), ones) 
} 

myfun(letters[1:5]) 
## Error in data.frame(x = x[[1]], ones) : 
## promise already under evaluation: recursive default argument reference or earlier problems? 

由於各種原因,我需要保持參數名稱與函數名稱相同(對於ones)。 我該如何強制在my fun.character內對參數進行評估?我也需要這個工作(它它):

myfun(letters[1:5], 1:5) 
## x ones 
## 1 a 1 
## 2 a 2 
## 3 a 3 
## 4 a 4 
## 5 a 5 

謝謝!

回答

1

人們需要深入研究R(臭名昭着的)環境以準確理解它在哪裏試圖找到ones。問題位於提供的方式中,默認參數在函數中進行評估。您可以在R手冊中看到this鏈接,並且還有一個解釋here

簡單的解決方案是告訴R在哪裏尋找它。它會爲您節省麻煩。在你的情況下,這是全球環境。

改變方法myfun.character告訴它尋找ones在全球環境:

myfun.character <- function(x, ones = get('ones', envir = globalenv())(x)) { 

    myfun(as.list(x), ones) 

} 

就足夠了這裏。

輸出:

myfun(letters[1:5]) 
# x ones 
#1 a 1 
#2 a 1 
#3 a 1 
#4 a 1 
#5 a 1 

myfun(letters[1:5], 1:5) 
# x ones 
#1 a 1 
#2 a 2 
#3 a 3 
#4 a 4 
#5 a 5 
+0

這向我指出瞭解決方案:對於其中本實施例中表示的問題的包,使用的'包::那些等效(X)'在'myfun.character'功能簽名。謝謝!但是,只是爲了縮短它,是否有任何方法來強制評估myfun.character中的package :: ones(x),使用問題中的原始函數簽名? –

+0

使用'::'會將R指向程序包的命名空間環境,所以您基本上告訴R在哪裏查找函數。使用'::'是正確的方法,在這種情況下,我認爲沒有辦法縮短它。 – LyzandeR

相關問題