2

do.callcurveに関する奇妙な問題に直面しています:

func1 <- function (m, n) {
  charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
  eval(parse(text = charac))
  return(func2)
}
func3 <- function (m, n) {
  my.func <- func1 (m, n)
  do.call("curve",list(expr = substitute(my.func)))
}

func1はfunc2を構成し、func3は構成されたfunc2をプロットします。しかし、func3を実行すると、次のエラーが表示されます。

> func3 (3, 6)
Error in curve(expr = function (x)  : 
  'expr' must be a function, or a call or an expression containing 'x'

ただし、func1を実行して出力を手動でプロットしている間 ( func3を適用せずに)、 func2 がプロットされます。

my.func <- func1 (3, 6)
do.call("curve",list(expr = substitute(my.func)))

ここで起こったことは私を混乱に導き、なぜdo.callがfunc3ローカル環境内でfunc2をプロットできないのかわかりません。

ありがとうございました

4

4 に答える 4

3

これを非常に複雑にしています-作成するときに特別なことをする必要はありませんf2:

f1 <- function (m, n) {
  function(x) m * x ^ n
}
f3 <- function (m, n) {
  f2 <- f1(m, n)
  curve(f2)
}
f3(3, 6)

もちろん、これは を削除することでより簡潔にすることができますf1:

f4 <- function (m, n) {
  f2 <- function(x) m * x ^ n
  curve(f2)
}
f4(3, 6)

https://github.com/hadley/devtools/wiki/Functionsで、R のスコープ規則 (これが機能する) の詳細を確認できます。

于 2013-01-12T17:24:01.943 に答える
1

これは の問題ではありませんがdo.callsubstitute グローバル環境でデフォルトで評価されます。したがって、どの環境置換が発生する必要があるかを伝える必要があります。ここでは明らかに func3 のローカル環境にあります。

これはうまくいくはずです:

 do.call("curve",list(expr = substitute(my.func,
                                           env = parent.frame())))

編集ありがとうドウィン

コメントで述べたように、 env デフォルトは現在の評価環境です。では、なぜ以下のコードが機能するのでしょうか? の助けを借りての答えsubstitute

関数への正式な引数、またはdelayedAssign()を使用して明示的に作成された場合、promiseの式スロットがシンボルを置き換えます。通常の変数の場合、env が .GlobalEnv でない限り、その値が代入されます。.GlobalEnv の場合、シンボルは変更されません。

env = parent.frame(n=1).GlobalEnvは、シンボル (my.func) が変更されない理由と同等です。したがって、正しい答えは次のようになります。

do.call("curve",list(expr = substitute(my.func,
                                               env = .GlobalEnv)))

テストするために、新しい R セッションを開きます。

func1 <- function (m, n) {
  charac <- paste ("func2 <- function(x)", m, "*x^", n, sep = "")
  eval(parse(text = charac))
  return(func2)
}
func3 <- function (m, n) {
  my.func <- func1 (m, n)

  do.call("curve",list(expr = substitute(my.func,env = .GlobalEnv)))
}

私が呼ぶよりも

 func3(2,6)
于 2013-01-12T10:53:53.687 に答える
1

これは機能します:

func3 <- function (m, n) {
   my.func <- func1 (m, n); print(str(my.func))
   do.call(curve, list(expr=bquote( my.func) ) )
 }
于 2013-01-12T11:26:41.143 に答える
-2

次の行を削除するだけです。

my.func <- func1 (m, n)

func3から。

于 2013-01-12T14:45:07.843 に答える