2

次のスニペットでvairable'loco'の値を変更するにはどうすればよいですか。

poco <- function() {

func <- function(x) {
    print(loco)
    loco <- loco+x
}

loco <- 123
func(1)
func(2)
}

この関数は次の結果をもたらします。

> poco()
[1] 123
[1] 123
4

4 に答える 4

5
poco <- function() {

func <- function(x) {
    print(loco)
    loco <<- loco+x
}

loco <- 123
func(1)
func(2)
}

この<<-演算子は、外部スコープに割り当てます。(のようにassign(..., env=...))。ただし、コメントで述べたように、これは通常悪い考えです。問題全体の概要を説明する、これを拡張した2番目の質問をしたい場合は、他にももっと良い選択肢があると思います。

注意しないと、お<<-尻に噛み付く可能性があります。このwiki記事を参照してください

最初の関数で何が起こっていたのかというと、関数は、スコープではなくローカルスコープに取り込まれ、ローカルスコープに割り当てられたときにloco <- loco + x、スコープの外を探します。funclocofunclocopoco

お役に立てば幸いです。

于 2012-10-09T15:31:53.473 に答える
5

Rには環境のスタックがあります。<-したがって、単純なコマンドまたはコマンドを使用して関数内の変数を変更している間=、その値は外部環境では変更されません。

そのためには、以下に示すように、いくつかのオプションがあります。

最初のオプション:

func <- function(x) {
    print(loco)
    # To modify value of "loco" just in the parent environment, but not globally
    loco <<- loco+x
}

2番目の(より良い)オプション:

func <- function(x) {
    print(loco)
    # Again modifies the varaible just in the parent environment, not globally
    assign("loco", loco + x, envir = sys.frame(-1))
}

そして3番目のオプション:

func <- function(x) {
    print(loco)
    # To modify the value of a global variable "loco"
    assign("loco", loco + x, envir = .GlobalEnv) 
}

次に、次のようになります。

loco <- 123
func(1) # 123
func(2) # 124
loco    # 126

オプション1と2を使用すると、ネストされた関数定義が複数ある場合は、親関数だけで値を変更しますが、グローバルには変更しないことに注意してください。

于 2012-10-09T15:32:04.903 に答える
3
poco <- function() {

  func <- function(loco,x) {
    print(loco)
    loco <- loco+x
    loco
  }

  loco <- 123
  loco <- func(loco,1)
  loco <- func(loco,2)
  loco
}
loco_final <- poco()
#[1] 123
#[1] 124
loco_final
#[1] 126
于 2012-10-09T15:25:18.077 に答える
3

loco一般的に、関数で変更されないのは良いことです。これらの種類のグローバル変数を使用しないことで、変数がより大きなスクリプトのそれぞれに干渉しないことが保証されます。

とで変数を使用するとblafunction_aますfunction_b。の履歴に依存するため、関数呼び出しの結果を予測することは困難ですbla。専門用語では、これは関数に副作用があると呼ばれます。これらを使用しないと、関数がより予測可能になり、デバッグが容易になります。さらに、スクリプトが大きくなると、新しい関数やコードスニペットblaが変更され、関数で何が起こるかが変わるという問題を防ぐことができます。

一般に、関数に変数が必要な場合は、それを変数として渡します。ただし、Rは関数の内側から関数の外側へのスコーピングを許可しますが、その逆は許可しません。詳細については、この最近の質問も参照してください。

于 2012-10-09T15:28:15.050 に答える