2012-03-24 4 views
10

私はHEREで議論に続き、なぜ<<-をRに惑わしているのか不思議です。それはどのような混乱の原因になりますか?なぜ `<< - `を使用しているのですか?それを避けるにはどうしたらいいですか?

また、どうすれば避けることができるかについてのヒントをお聞きしたいと思います。<<-私は次のことを頻繁に使用します。たとえば:

### Create dummy data frame of 10 x 10 integer matrix. 
### Each cell contains a number that is between 1 to 6. 
df <- do.call("rbind", lapply(1:10, function(i) sample(1:6, 10, replace = TRUE))) 

は何を達成したいことは1で、すべての数をダウンシフトすることである、すなわちすべての2Sは1秒となり、すべての3Sは、など。したがって、すべてのnn-1来ることになる2来ることでしょう。この場合

df.rescaled <- df 
sapply(2:6, function(i) df.rescaled[df.rescaled == i] <<- i-1)) 

、どのように私は<<-を避けることができます。私は、次のことで、これを実現しますか? kohskeが指摘するように、それがない限り、トップの環境に割り当てるので、あなたは、約(グローバルアサインメントとして<<-と考えることができ

df.rescaled <- sapply(...) 
+0

はhttp://stackoverflow.com/questions/14166207/avoiding-global-variables-in-r/14166812も参照してください。 #14166812 –

答えて

16

まずポイント

<<-は、グローバル変数に割り当てるませ演算子です。変数を最も近い親環境に割り当てようとします。あなたがReduceを使用していることを行うことができます

> a <- 1 
> f() 
> a # the global `a` is not affected 
[1] 1 

2点目

、その後、

f <- function() { 
    a <- 2 
    g <- function() { 
     a <<- 3 
    } 
} 

Reduce(function(a, b) {a[a==b] <- a[a==b]-1; a}, 2:6, df) 

またはapplyをだから、たとえば、これは混乱を行います

apply(df, c(1, 2), function(i) if(i >= 2) {i-1} else {i}) 

しかし

単に、これで十分です:

ifelse(df >= 2, df-1, df) 
+0

私のコードの代わりにありがとう。とても有難い。 Reduce関数について詳しく説明できますか?私は読んだ後でも論理フローについてあまり明確ではない?Reduce。 2つの変数でReduce内に関数を作成しようとしていることがわかります。 '='から 'b' - ' 1'までのすべての 'a'のために。それに続いて '; a'と残りの構文があります。 – JackeJR

+0

' Reduce'は 'Fold'としても知られています。これは関数型プログラミングでよく使われるメソッドです。ここに簡単な説明があります。 [wikipedia](http://en.wikipedia.org/wiki/Fold_(higher-order_function)) – kohske

+0

詳しい説明はhttp://stackoverflow.com/a/10904810/2338862を参照してください。 – Thomas

5

:理想的には私はの線に沿って別の変数にsapply結果パイプにできるようにしたいでしょう変数名はより近位の環境に存在します)。これが悪い理由の例はここにある:

Examples of the perils of globals in R and Stata

+0

+1のリンクです。ありがとう! – JackeJR

+1

'x << - value'は' assign( 'x'、value、inherits = TRUE)と等価なので、囲む環境を検査する代入として '<< - 'を考えるのが理にかなっています。 'assign( 'x'、value、pos、.GlobalEnv)'とまったく異なる目的のために使用します。 –