2017-10-31

Rのお勉強

R言語を勉強しています。org-modeから使うとこんな感じで簡単にグラフを書けてとても便利なのです。

ぱっと見簡単そうな言語なのですが、細部を見ていくと案外ひっかかる言語です。

スカラー型がない所とか。numeric(integerとかdouble)とかcomplex(複素数値)とかlogical(論理値)とかcharacter(文字というか文字列)といった型名があるのですが、全部ベクトル型なので0個以上複数の値を保持できます。

スカラー型がないところというよりは一見スカラー型に見える場合があるところが引っかかりの元なんでしょうね。単に 1 と書くとスカラーのように見えますが実際には要素数(長さ)1のベクトルを書いたことになっているという。型名も vector<numeric> とか numeric[1] とかではなく numeric だけで数値ベクトル型を表すので、最初 mode(1)mode(c(1,2,3)) が同じ型名 numeric になっているのを見てびっくりするわけです。

ベクトルを作るとされている c 関数も作るというと語弊があって、ベクトルを合成(combine)する関数だっりします。 c(1,2,3) は要素数1のベクトル3つを合成して要素数3のベクトル1つを返すというように。

1 #要素数1の数値型(double)ベクトル
c(1) #こう書いても同じ

c(1,2,3) #要素数3の数値型(double)ベクトル
c(c(1), c(2), c(3)) #こう書いても同じ

1:3 #結果はc(1L,2L,3L)と同じ数値型(integer)ベクトル
c(1L, 2L, 3L) #こう書いても同じ
seq(1,3) #こう書いても同じ
c(1:1, 2:2, 3:3) #こう書いても同じ
c(1:1, 2:3) #こう書いても同じ

オブジェクトと値と属性と変数の関係もちょっと分かりづらい、というかイマイチよく分かってません。オブジェクトを別の変数に代入すると同じ値と属性を持ったオブジェクトが新しく出来るみたいなのですが、それならまだ変数になる前の無名のオブジェクトはどうなっているのか、とか。

# 変数(オブジェクト?)aに属性を設定したり取得したり
a <- c(1,2,3)
attr(a, "attr1") <- "value1" # aの"attr1"属性を"value1"へ設定
attr(a, "attr1") # "attr1"属性を取得

# 変数bへaをコピー
b <- a # aの値と属性がbへコピー
attr(b, "attr2") <- "value2" # bの"attr2"属性を"value2"へ設定。aはそのまま

# 変数に入れないでnames属性を指定してみる
c(first=1, second=2, third=3) # "names"属性をc("first", "second", "third")へ設定
attr(c(first=1, second=2, third=3), "names") # "names"属性を取得 c("first", "second", "third")
c(first=1, second=2, third=3)["second"] # 名前で要素を指定

# 変数に入れないで属性を設定してみる
attr(c(1,2,3), "attr3") <- "value3" #エラー:target of assignment expands to non-language object

(function(obj, name, value){attr(obj, name)<-value; obj;})(c(1,2,3), "attr4", "value4") #OK

うーん??

基本型一覧(2.1 Basic types - R Language Definitionより):

  mode(x) storage.mode(x) typeof(x) class(x) x=作成例1 作成例2  
論理値(ベクトル) "logical" "logical" "logical" "logical" TRUE c(TRUE,FALSE) ※単純な数字も長さ1のベクトル
整数値(ベクトル) "numeric" "integer" "integer" "integer" 1L c(1L,2L) ※単純な数字も長さ1のベクトル
倍精度実数値(ベクトル) "numeric" "double" "double" "numeric" 1.0 c(1.0,1.0) ※単純な数字も長さ1のベクトル
複素数値(ベクトル) "complex" "complex" "complex" "complex" 1+1i c(1+3i,2+4i) ※単純な数字も長さ1のベクトル
文字列(ベクトル) "character" "character" "character" "character" "a" c("abc","def") ※単純な数字も長さ1のベクトル
リスト "list" "list" "list" "list" list() list(1,2) 任意の型を要素とするコレクション
シンボル "name" "symbol" "symbol" "name" quote(x)    
関数オブジェクト "function" "function" "closure" "function" function(x,y) x+y    
call "call" "language" "language" "call",etc… quote(x+y*z)   class(quote(x<-1))は"<-"になったり色々する。
expression(ベクトル) "expression" "expression" "expression" "expression" expression(1+0:9) expression(x,y,z+1)  
NULL "NULL" "NULL" "NULL" "NULL" NULL pairlist() 属性を設定することは出来ない
Promiseオブジェクト              
ドットドットドット              
環境オブジェクト             フレーム(シンボルテーブル)と外の環境への参照
対リストオブジェクト "pairlist" "pairlist" "pairlist" "pairlist" pairlist(1,2,3) as.pairlist(list(1,2,3))  

よく使われるクラス:

  mode(x) storage.mode(x) typeof(x) class(x) x=作成例  
matrix mode(要素) storage.mode(要素) typeof(要素) "matrix" matrix(c(1,2,3,4),2,2,byrow=TRUE)  
array mode(要素) storage.mode(要素) typeof(要素) "array" array(c(1,2,3,4,5,6,7,8), c(2,2,2)) matrixの多次元版
data.frame "list" "list" "list" "data.frame" mode(data.frame(name=c("orange", "banana"), price=c(100, 200)))  
Date "numeric" "double" "double" "Date" as.Date("2017-10-30")  
POSIXlt(ローカル時間) "list" "list" "list" c("POSIXlt" "POSIXt") strptime("2017-10-30 12:34:56", "%Y-%m-%d %H:%M:%S") 年月日時分秒曜日dst
POSIXct(カレンダー時間) "numeric" "double" "double" c("POSIXct" "POSIXt") Sys.time() 1970年1月1日からの経過秒
factor "numeric" "integer" "integer" "factor" factor(c("Choki"),c("Guu","Choki","Paa"))