2017-07-25 34 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

相关问题