Love澤's Room

技術系ネタをまとめていたブログ。カテゴリにこだわらず更新していこうかと思います。

Rの演算子「<-」と「=」と「<<-」の違い

Rをいじっているのだが、タイトルの通り、代入演算子の違いがわからなかった。それぞれ以下のように呼ぶそう。

(参考サイト)
http://isyus2.yz.yamagata-u.ac.jp/xoops/Data/R_v3.pdf
http://cse.naro.affrc.go.jp/takezawa/r-tips/r/28.html


通常の代入操作については、「<-」「=」のどちらを使っても構わないそう。いわゆる、プログラミングで一般的に使われる代入と同じイメージ。ただし、S4クラスやS5クラスの中でデータの型を指定するときは「<-」ではエラーとなり「=」を使用しなければならないっぽい。気を使うのが面倒。

永続代入演算子は、あるメソッドの中からメソッド外の変数に値を代入する際に使用する演算子。個人的にはメソッドの中からメソッド外の変数に代入なんてすんなよって思う(古い考え?)。使う場面としては、S5クラスで定義されているフィールドに代入する際など。

下記サイトに載っているプログラム例を参考にしながら、自分なりに少しずつ手を加えたプログラムを以下に示す。
「<-」「=」「<<-」の使い方を示せればと。
R5クラス | 参照渡しを実現する,リファレンス,ポインター

Asagao = setRefClass(
  # クラス名
  Class = "Asagao",     # 通常の記述法
  # Class <- "Asagao",  # Asagaoという値をもつClassという変数が生成される。ただし、クラスとしての機能は実装できる。
  # 上記どちらかの記述がなければ、クラスとして実装できない(エラーがとなる)。

  # 継承
  contains = c("Flower"),     # 通常の記述法
  # contains <- c("Flower"),  # Flowerという値を持つcontainsという変数が生成される。
  
  # フィールド
  fields = list (     # 通常の記述法
  # fields <- list (  # seeds, speciesという変数(カラム?)を持つlistが生成される。
                      # また、seedsは"numeric"という値をspeciesは"character"という値をもつ
    seeds   = "numeric",   # 種の数
    species = "character"  # 種類
  ),

  # フィールド                           # この書き方だと、エラーとなる
  # fields = list (  # 通常の記述法      # |
  #   seeds   <- "numeric",   # 種の数  # |
  #   species <- "character"  # 種類    # |
  # ),                                 # |
  
  # method
  methods = list (
    # コンストラクタ
    initialize = function(color=NULL, leaves=NULL, species=NULL) {    # 通常の記述法
    # initialize = function(color=NULL, leaves=NULL, species=NULL) {  # エラー
      if (is.null(color)) {
        color <<- "skyblue"   # 通常の記述法
        # color <- "skyblue"  # エラー
      } else {
        color <<- color
      }
      
      if (is.null(leaves)) {
        leaves <<- 50
      } else {
        leaves <<- leaves
      }
      
      if (is.null(species)) {
        species <<- "昼顔"
      } else {
        species <<- species
      }
    },
    
    # 葉っぱの枚数から生育状態を計算して、その状態を conditions 変数に保存
    CalcConditions = function() {
      x = 2
      y = 4
      conditions <<- leaves * x - y
    },
    
    # 現在の生育状態から種子数を予測し、予測した種子数を seeds に保存
    EstimateSeeds = function() {
      seeds <<- round(conditions / 10 + 50)
    },
    
    getConditions = function() {
      conditions <<- leaves * 2
      return(conditions)
    },
    getConditions2 = function() {
      conditions <<- CalcConditions()
      return(conditions)
    }
  )
)