//間瀬茂 COLOR(RED){SIZE(30){データフレームを作る、操作する}} R の多くの関数はデータフレームと呼ばれるオブジェクトを対象とする.データフレームは、同じ長さの複数の数値ベクトル,文字ベクトル等を成分とする、data.frame属性を持つリストであるが,そのものとしては行列のような外見を持つ.各行・列はラベルを必ず持ち,それを用いた添字操作が可能である.データフレームの各行は一つの観測値(case)を表現する。データフレームの各列は一つの変数(項目)を表現する. #contents ~ *データフレームを作る **データファイルを SIZE(20){read.table()} 関数で読み込んでデータフレームを作る データフレーム変数を得る基本は、特別の形式をもつデータファイルを SIZE(20){read.table()} 関数で読み込むことである。 ***行ラベルのないデータファイル (header=TRUE) 行ラベルの無いデータファイル "temp1.data" の内容 Price Floor Area Ch 52.0 111.0 830 yes 54.8 128.0 710 no 57.5 101.0 1000 yes 59.3 131.0 900 no オプション header=TRUE 付きでデータフレームとして読み込む。最初の行は見出しで,列ラベルとされる。行ラベルは与えられておらず,自動的にヘッダー(通し番号 1,2,3,4)が付け加えられる > HP <- read.table("temp1.data", header=TRUE) > HP Price Floor Area Ch # 形式的に 4x4 行列.行・ラベルが自動的に付加される 1 52.0 111 830 yes 2 54.8 128 710 no 3 57.5 101 1000 yes 4 59.3 131 900 no > HP$Price # 第一列.HP[[1]] でも良い。 [1] 52.0 54.8 57.5 59.3 # 数字は数値として読み込まれる > HP[["Ch"]] # これも可.第4列 [1] yes no yes no Levels: no yes # 文字列は因子として読み込まれる > HP[1,] # 第一行.列ラベルが付く Price Floor Area Ch 1 52 111 830 yes > HP[2,] Price Floor Area Ch 2 54.8 128 710 no > HP[2,2] # 第2列第2行の要素 [1] 128 > HP[2,"Floor"] # この形式も可 [1] 128 > dim(HP) # 行列と同様次元を持つ [1] 4 4 ***行ラベルつきのデータファイル (header=FALSE) 行ラベル "Am", "St", "Yo", "Ht" 付きのデータファイル "temp2.data" の内容 Price Floor Area Ch Am 52.0 111.0 830 yes St 54.8 128.0 710 no Yo 57.5 101.0 1000 yes Ht 59.3 131.0 900 no (既定の) header=FALSE で読み込み > HP <- read.table("temp2.data") > HP Price Floor Area Ch Am 52.0 111 830 yes St 54.8 128 710 no Yo 57.5 101 1000 yes Ht 59.3 131 900 no > HP[2,2] # 第2行第2列成分 [1] 128 > HP["St","Area"] # 第2行第3列成分 [1] 710 > HP["St","Ch"] # 第2行第4列成分 [1] no Levels: no yes もう一つの行ラベル付きデータファイル "temp3.data"。行ラベルは文字列 "32", "13", "5", "71" と見なされる Price Floor Area Ch 32 52.0 111.0 830 yes 13 54.8 128.0 710 no 5 57.5 101.0 1000 yes 71 59.3 131.0 900 no > HP <- read.table("temp3.data") # 既定値の header=FALSE で読み込み > HP Price Floor Area Ch 32 52.0 111 830 yes 13 54.8 128 710 no 5 57.5 101 1000 yes 71 59.3 131 900 no > HP[32,2] # エラー [1] NA > HP["32",2] # 正しい.HP[1,2] でも良い [1] 111 *** 列(i.e. 変数名)ラベルの無いデータファイル a 1 2 yes # 列ラベルの無いデータファイル "temp.data" b 2 3 no c 5 7 yes > x=read.table("temp.data") # 既定の header=FALSE で読み込み > x V1 V2 V3 V4 # 列(変数名)ラベルが自動的につけられる 1 a 1 2 yes 2 b 2 3 no 3 c 5 7 yes > y=read.table("temp.data",header=TRUE) > y a X1 X2 yes # ナンセンスな結果 1 b 2 3 no 2 c 5 7 yes **データフレームを直接作る。関数 data.frame() *** 数値ベクトルからデータフレームを作る > data.frame(vx = 1:4, vy = rnorm(4)) # 4x4 のデータフレーム。列ラベル vx,vy vx vy 1 1 -0.8481768 2 2 0.8831475 3 3 0.2178012 4 4 0.2753476 *** 数値行列からデータフレームを作る > x [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 > data.frame(x) X1 X2 X3 1 1 5 9 2 2 6 10 3 3 7 11 4 4 8 12 > data.frame(x,row.names=c("a","b","c","d")) # 行ラベルを指定 X1 X2 X3 # 列ラベルは後から変更するしかない(?) a 1 5 9 # x が列ラベルを持つ行列なら、それを継承する b 2 6 10 c 3 7 11 d 4 8 12 > x=matrix(1:4, c(2,2), dimnames=list(c("Ca","Cu"),c("Ag","Pt"))) > x # 行・列ラベル付き行列 Ag Pt Ca 1 3 Cu 2 4 > data.frame(x) # データフレームは行・列ラベルを継承する Ag Pt Ca 1 3 Cu 2 4 ** 行列をデータフレームとしてファイルに記録し、それをまた読み込む。write.table(), read.table() 関数 (2003.12.25) 注意:MASS ライブラリ中の write.matrix 関数も write.table 関数と同様の機能を持つ。 > x <- matrix(1:12, ncol=3) # 数値行列 > x [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 > write.table(x, file="temp.dataframe") # x をファイルに書き出す(同時にデータフレームに強制変換される) > xx <- read.table("temp.dataframe") # 再び読み込み > xx # データフレームになっている X1 X2 X3 # 変数ラベルが付け加えられている 1 1 5 9 2 2 6 10 3 3 7 11 4 4 8 12 "X1" "X2" "X3" # ファイル temp.dataframe の中身は "1" 1 5 9 "2" 2 6 10 "3" 3 7 11 "4" 4 8 12 * データフレームの操作 ** 列の消去 > HP[[2]] <- NULL # 第2列を消去 > HP Price Area Ch 32 52.0 830 yes 13 54.8 710 no 5 57.5 1000 yes 71 59.3 900 no **列の置き換え > HP[[2]] <- c(1,2,3,4) # 第2列を置き換え > HP Price Floor Area Ch 32 52.0 1 830 yes 13 54.8 2 710 no 5 57.5 3 1000 yes 71 59.3 4 900 no **サブデータフレームの取り出し > HP[c(1,3,4),] # 第1,3,4行を抜き出す(結果もデータフレーム) Price Floor Area Ch 32 52.0 1 830 yes 5 57.5 3 1000 yes 71 59.3 4 900 no ** 行・列ラベルの取り出し、変更 > rownames(HP) # 行ラベルの取り出し [1] "32" "13" "5" "71" > colnames(HP) # 列ラベルの取り出し [1] "Price" "Floor" "Area" "Ch" > colnames(HP) <- c("P","F","A","C") # 列ラベルの変更 > HP P F A C 32 52.0 111 830 yes 13 54.8 128 710 no 5 57.5 101 1000 yes 71 59.3 131 900 no > rownames(HP) <- c("01","02","03","04") # 行ラベルの変更 > HP P F A C 01 52.0 111 830 yes 02 54.8 128 710 no 03 57.5 101 1000 yes 04 59.3 131 900 no > rownames(HP) <- c("1","2","3","4") # 両者は同じ効果を持つ > rownames(HP) <- c(1,2,3,4) **SIZE(20){cbind()} で行ラベルが同じ二つのデータフレームを連結 (つまり、変数を増やす) > x # 第1のデータフレーム Rooms Color 1 4 Red 2 6 Brown 3 7 Yellow 4 3 Grey > y # 第2のデータフレーム Price Floor Area Ch 1 52.0 111 830 yes 2 54.8 128 710 no 3 57.5 101 1000 yes 4 59.3 131 900 no > z <- cbind(y,x) > z # 結合されたデータフレーム Price Floor Area Ch Rooms Color 1 52.0 111 830 yes 4 Red 2 54.8 128 710 no 6 Brown 3 57.5 101 1000 yes 7 Yellow 4 59.3 131 900 no 3 Grey **SIZE(20){rbind()} で列ラベルが同じ2つのデータフレームを連結 (つまりデータ数を増やす) > y Price Floor Area Ch 1 52.0 111 830 yes 2 54.8 128 710 no 3 57.5 101 1000 yes 4 59.3 131 900 no > yy Price Floor Area Ch 5 62.0 109 720 yes 6 85.8 182 650 no 7 72.5 115 567 yes > rbind(y,yy) Price Floor Area Ch 1 52.0 111 830 yes 2 54.8 128 710 no 3 57.5 101 1000 yes 4 59.3 131 900 no 5 62.0 109 720 yes 6 85.8 182 650 no 7 72.5 115 567 yes > rownames(yy)<-c(3,4,7,8) # わざと y と yy の行ラベルが一部一致するようにする > yy Price Floor Area Ch 3 52.0 111 830 yes 4 54.8 128 710 no 7 57.5 101 1000 yes 8 59.3 131 900 no > rbind(y,yy) Price Floor Area Ch 1 52.0 111 830 yes 2 54.8 128 710 no 3 57.5 101 1000 yes 4 59.3 131 900 no 31 52.0 111 830 yes # 重複する行ラベルは自動的に付け替えられる 42 54.8 128 710 no # 重複する行ラベルは自動的に付け替えられる 7 57.5 101 1000 yes 8 59.3 131 900 no **データフレームを行列に変換。関数 data.matrix() > HP # これはデータフレーム Price Floor Area Ch 32 52.0 111 830 yes 13 54.8 128 710 no 5 57.5 101 1000 yes 71 59.3 131 900 no > x <- data.matrix(HP) > x # これはただの行列 (見たところ同じ) Price Floor Area Ch # 行・列ラベルをしっかり継承 32 52.0 111 830 2 # 因子 Ch はその内部表現である数値に変換されている 13 54.8 128 710 1 5 57.5 101 1000 2 71 59.3 131 900 1 > attributes(HP) # HP の属性をみる $names # 列(変数)名 [1] "Price" "Floor" "Area" "Ch" $class [1] "data.frame" # 確かに data.frame 属性を持つ $row.names # 行(データ)名 [1] "32" "13" "5" "71" > attributes(x) # x の属性をみる $dim [1] 4 4 $dimnames $dimnames[[1]] # これは行列の行ラベル [1] "32" "13" "5" "71" $dimnames[[2]] # これは列ラベル [1] "Price" "Floor" "Area" "Ch" > str(x) # str() 関数の結果も確かに異なる num [1:4, 1:4] 52 54.8 57.5 59.3 111 128 101 131 830 710 ... - attr(*, "dimnames")=List of 2 ..$ : chr [1:4] "32" "13" "5" "71" ..$ : chr [1:4] "Price" "Floor" "Area" "Ch" *データフレームに関する情報を得る ** データフレームに関する詳細な情報。関数 str() > HP # データフレーム Price Floor Area Ch 32 52.0 111 830 yes 13 54.8 128 710 no 5 57.5 101 1000 yes 71 59.3 131 900 no > str(HP) # データフレームの詳細 `data.frame': 4 obs. of 4 variables: $ Price: num 52 54.8 57.5 59.3 # HP$Price は数値ベクトル $ Floor: num 111 128 101 131 # $ Area : int 830 710 1000 900 # HP$Area は整数値ベクトル $ Ch : Factor w/ 2 levels "no","yes": 2 1 2 1 # no, yes は因子 2, 1 と解釈されている ** データフレームオブジェクトかどうか検査。関数 is.data.frame() > is.data.frame(HP) # データフレームオブジェクトか? [1] TRUE # 然り