2017-07-25 13 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(x)としてones引数のデフォルト値を設定し、別の方法を定義するとき、私はエラーを取得する:

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

onesを見つけようとする場所を正確に理解するには、R(悪名高い)環境を深く見る必要があります。問題は、提供された方法で位置付けられ、デフォルトの引数は関数内で評価されます。 Rマニュアルのthisリンクもご覧になれます。説明はhereです。

簡単な解決策は、Rにどこを探すかを教えることです。それはあなたに面倒を保存します。あなたの場合、それは地球環境です。地球環境にonesを探すために、それを伝えるための方法myfun.characterを変更

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内のパッケージ:: ones(x)の評価を強制する方法はありますか? –

+0

'::'を使ってRをパッケージの名前空間環境に向けるので、Rを見てどこに関数を見つけるかを本質的に指示しています。 '::'を使うのは正しい方法ですが、この場合には短縮する方法はないと思います。 – LyzandeR

関連する問題