最初に新しい変数を定義しx
、次にx
その本体内で(引数としてではなく)必要な関数を作成しました。以下のコードを参照してください
x <- c(1,2,3)
f1 <- function() {
x^2
}
rm(x)
f2 <- function() {
x <- c(1,2,3)
f1()
}
f(2)
Error in f1() : object 'x' not found
を削除しx
、f2
最初に定義x
してから実行する新しい関数を定義すると、f1
オブジェクトx
が見つかりませんでした。
なぜこれが機能しないのか、そしてこの問題をどのように克服できるのかを知りたかっただけです。のx
引数として名前になりたくありませんf1
。
これがどんな問題なのかわからないので、適切なタイトルを付けてください。
要するに:あなたは動的スコープを期待していますが、Rの字句スコープの犠牲者です:
動的スコープ=コマンドの囲み環境は実行時に決定されます
字句スコープ=コマンドの囲み環境は「コンパイル時」に決定されます
x
現在の環境と親環境での変数のルックアップパスを理解するには、このコードを試してください。
これは、両方の関数が環境を共有していないことを示しているため、x
で定義されているf2
ため、見つけることができません。
# list all parent environments of an environment to show the "search path"
parents <- function(env) {
while (TRUE) {
name <- environmentName(env)
txt <- if (nzchar(name)) name else format(env)
cat(txt, "\n")
if (txt == "R_EmptyEnv") break
env <- parent.env(env)
}
}
x <- c(1,2,3)
f1 <- function() {
print("f1:")
parents(environment())
x^2
}
f1() # works
# [1] "f1:"
# <environment: 0x4ebb8b8>
# R_GlobalEnv
# ...
rm(x)
f2 <- function() {
print("f2:")
parents(environment())
x <- c(1,2,3)
f1()
}
f2() # does not find "x"
# [1] "f2:"
# <environment: 0x47b2d18>
# R_GlobalEnv
# ...
# [1] "f1:"
# <environment: 0x4765828>
# R_GlobalEnv
# ...
可能な解決策:
x
地球環境で宣言する(カプセル化が不足しているため、プログラミングスタイルが悪い)
関数パラメーターを使用します(これが関数の目的です)
のx
呼び出しごとに常に同じ値がある場合は、クロージャを使用しますf1
(初心者向けではありません)。@JohnColemanからの他の回答を参照してください...
2.を使用することを強くお勧めします(パラメーターとしてxを追加します-なぜこれを避けたいのですか?)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加