データフレームとは
データフレームとは data.frame クラスを持つリストのことであり, 数値ベクトルや文字ベクトル,因子ベクトル(文字型ベクトル)などの異なる型のデータをまとめて1 つの変数として持っている. 外見は行列と同じ 2 次元配列であるが,データフレームの各行・列はラベルを必ず持ち, ラベルによる操作が可能である点が普通の行列と異なる. しかも各列の要素の型はバラバラでも構わないので, ベクトルやリストで持っているデータをデータフレームに変換することで統計解析がやりやすくなる.
データフレームを作成する方法は以下のような方法がある.
- ベクトル(や行列,リストなど)からデータフレームを作成する
- ファイルにあるデータを読み込んでデータフレームを作成する
まずは前者の方法を紹介する.「性別」「身長」「体重」データをベクトルで用意しておき, それらを関数 data.frame() で 1 つのデータフレームに変換する.
data.frame(列名1 = ベクトル1, 列名2 = ベクトル2, ... ) |
実際に関数 data.frame() でデータフレームを作成してみる.
|
データフレーム x
|
行列や配列からデータフレームを作成することも出来る. 例えば行列 x をデータフレームに変換する場合は data.frame(x) とすればよい. ラベル名を指定しない場合は自動でラベル名が振り分けられる.
データフレームの使用例
データフレーム x を生成すると, 「データフレーム x の『性別』データ」や「データフレーム x の『体重』データ」としてデータを取り出すことが出来る. 取り出す方法は「データフレーム名$列名」などとすればよい.
x$HEIGHT # データフレーム x の『身長』データ [1] 158 162 177 173 166 mean( x$WEIGHT ) # データフレーム x の『体重』データの平均 [1] 59.8 x[,2] # データフレーム x の 2 列目を表示する [1] 158 162 177 173 166 |
データフレームという形にすることで,要素それぞれに『性別』や『身長』などの属性を付けることに成功した. その恩恵の一つとして,関数 summary() を使うことでデータフレームの列ごとの特徴を見ることが出来る.すると上から順に「最小値,第 1 四分位点,中央値,平均,第 3 四分位点,最大値」が表示される.
summary(x) SEX HEIGHT WEIGHT F:2 Min. :158.0 Min. :51.0 M:3 1st Qu.:162.0 1st Qu.:55.0 Median :166.0 Median :57.0 Mean :167.2 Mean :59.8 3rd Qu.:173.0 3rd Qu.:64.0 Max. :177.0 Max. :72.0 |
関数 by(データフレーム,層別する変数,関数名) を使うことでデータフレームの層ごとに集計を行うことができる. 以下では,データフレーム x について男女別に要約統計量を求めている.
by(x, x$SEX, summary) x$SEX: F SEX HEIGHT WEIGHT F:2 Min. :158 Min. :51 M:0 1st Qu.:159 1st Qu.:52 Median :160 Median :53 Mean :160 Mean :53 3rd Qu.:161 3rd Qu.:54 Max. :162 Max. :55 ------------------------------------------------------------ x$SEX: M SEX HEIGHT WEIGHT F:0 Min. :166.0 Min. :57.00 M:3 1st Qu.:169.5 1st Qu.:60.50 Median :173.0 Median :64.00 Mean :172.0 Mean :64.33 3rd Qu.:175.0 3rd Qu.:68.00 Max. :177.0 Max. :72.00 |
ファイルからデータを読み込む
作業ディレクトリの変更
データを扱う際,まず,データがあるディレクトリ(フォルダ)に作業ディレクトリを変更する必要がある. もし,データが作業ディレクトリに無い場合は,ファイルを指定する場所にファイルのパスを指定すればよい(例:x <- read.table("C:/data.txt") ).
data01.txt のようなデータは,関数 read.table() で読む.データファイルに列名が無いので,R が勝手に列名を決めている.
|
data01.txt
|
data02.txt のように,1行目にコメントが入っているデータは,関数 read.table() の引数 skip(何行読み飛ばすか)に 1 を指定する.
|
data02.txt
|
data03.txt のように,1行目に列名が入っているデータは,関数 read.table() の引数 header(列名があるか否か)に T を指定する.
|
data03.txt
|
data04.txt のように,1行目にコメント,2行目に列名が入っているデータは,引数 header に T を,skip(何行読み飛ばすか)に 1 を指定する.
|
data04.txt
|
data05.txt のように,データ間がコンマ( ,)で区切られている場合は,引数 sep(データの区切り文字)に "," を指定する.また,タブで区切られている場合は "\t" を指定すればよい.
|
data05.txt
|
関数 read.table() の引数を以下に示す.
引数 |
機能 |
sep = "" |
データとデータの区切り文字を指定する. |
skip = 0 |
最初の行 から読み飛ばす行数を指定する.指定しない場合はファイルの 1 行目から読む. |
nrows = -1 |
何行目まで読むかを指定する .指定しない場合(負の値の場合)はファイルの終わりまで読む). |
header = F |
「1行目は列名が書かれている」か否かを指定する.列名が書かれている場合で,F を指定すると不具合が生じる. |
comment.char |
コメント行を表す記号(デフォルトは \# )を指定する. |
row.names=NULL |
1 から始まる番号が行名として生成される. |
row.names="列名" |
指定した列のデータが行名として使われる.使われた列はデータフレームの変量としては取り除かれることになる. |
row.names=列番号 |
上記と同じ. |
row.names=文字型ベクトル |
ベクトルの各要素が行名となる.ただし行数と同じ長さのベクトルを指定する. |
read.table() のラッパークラスとして以下のような関数が用意されている.
関数 |
header |
sep |
quote |
dec |
用途 |
read.csv("ファイル名") |
T |
"," |
"\"" |
"." |
区切りがコンマの場合 |
read.csv2("ファイル名") |
T |
";" |
"\"" |
"," |
区切りがコロン&小数点がコンマの場合 |
read.delim("ファイル名") |
T |
"\t" |
"\"" |
"." |
区切りがタブの場合 |
read.delim2("ファイル名") |
T |
"\t" |
"\"" |
"," |
区切りがタブ&小数点がコンマの場合 |
read.fwf("ファイル名") |
F |
"\t" |
"\"" |
"." |
一行の各欄の桁数 widths を指定して読み込む |
EXCEL のデータを読み込む
read.csv("ファイル名") とすればよい.列名が無い場合は,関数 read.csv() の引数 header に F を指定し,引数 col.names に列名を指定すれば良い.
|
|
EXCELのセルをコピー&ペーストする方法
まず,EXCEL のセルをコピーする.
x < read.delim("clipboard") |
関数 write.table(x, "clipboard", sep="\t") でデータ x をクリップボードにコピーすることが出来,この後 EXCEL シートにデータをペーストすることが出来る.
列名をコピーしなかった場合は以下のようにすればよい.
x < read.delim("clipboard", header=F) |
xlsファイルを直接読み込む方法
gregmisc パッケージと Perl を用意することで,xls 形式のファイルを直接読み込むことが出来る.関数は read.xls() を使い,引数 sheet でシート番号を指定することが出来る.
library(gregmisc) x <- read.xls("data01.xls", sheet=1) |
ただし,Windows 版 R の場合で Perl を入れる必要がある.以下に,ActiveState:
ActiveState : http://www.activestate.com/
からインストールする.
データへのアクセス方法
まず,たたき台となるデータフレーム x を作成する.
|
データフレーム x
|
このデータフレーム x にアクセスする方法を紹介する.
コマンド |
機能 |
x$列名,x["列名"],x[["列名"]] |
列データ(例えば SEX や WEIGHT )にアクセスする. |
x[2], x[[2]] |
2 番目の列データにアクセスする. |
x[3, 2], x[[3, 2]] |
3 行 2 列目のデータにアクセスする. |
x[[3, "列名"]], x[[3, "列名"]] |
指定した列の 3 行目のデータにアクセスする. |
x[c(1, 2)] |
1 列目と 2 列目のデータにのみアクセスする.x[ , c(1, 2)] も同じ. |
x[c(3, 4), ] |
3 行目と 4 行目のデータにのみアクセスする. |
x[c(1,3,5,2,4), ] |
順序ベクトル c(1,3,5,2,4) の順に行を並べかえる. |
x[ ,c(T,F,T)] |
論理ベクトル c(T,F,T) が TRUE となっている列にのみアクセスする. |
x[x$SEX=="F", ] |
性別が F(女性)である行にのみアクセスする. |
x[x$SEX=="F" & x$WEIGHT>50, ] |
性別が F(女性)かつ体重が 50kg 以上である行にのみアクセスする. |
以下にいくつかの例を示す.
データの変更や追加,消去方法はベクトルや行列とほぼ同じである.例えば x[[2]] や x[2] でデータフレームの 2 列目にアクセスすることが出来る.
x[[2]] # 第 2 列のデータを見る -> a[2] でもよい [1] 158 162 177 173 166 x[c(1,3,4),] # 第 1, 3, 4 行を抜き出す SEX HEIGHT WEIGHT 1 F 158 51 3 M 177 72 4 M 173 57 |
データを消去する場合は,行や列に NULL を代入すればよい.
x[[2]] <- NULL # 第2列を消去:列の消去は NULL を代入する.x <- x[,-c(2)] でも同じ結果 x SEX WEIGHT 1 F 51 2 F 55 3 M 72 4 M 57 5 M 64 |
データをセル形式で閲覧・編集
データをセル形式で見る場合は関数 edit(データフレーム名) を用いる.
x <- edit(x) |
データをクリックすることで値を編集することが出来,列名をクリックすれば数値型と文字型の選択,列名の変更などが行える.編集が終了したらウインドウを閉じることで,変更が反映される.
データの結合と整列に関する関数一覧
データ加工に関する関数の一覧はこちら(以下に出てくる x と y はデータフレームとする).
コマンド |
機能 |
ncol(x) |
x の列数(項目数)を求める. |
nrow(x) |
x の行数(データ数)を求める. |
names(x) |
x の列名を表示する. |
rbind(x, y) |
x と y を縦に並べて結合する(x と y の列名が全て同じ場合). |
cbind(x, y) |
x と y を横に並べて結合する(x と y の行数が同じ場合). |
data.frame(x, y) |
x と y を横に並べて結合する(x と y の行数が同じ場合). |
merge(x, y) |
x と y を併合(マージ)する.通常は引数に all=T を指定し,データを全て残す.all=T を指定しなければデータの共通部分が結果として返される. |
まず,データフレーム D1 と D2 を作成する.
|
データフレーム D1
|
データフレーム D2
|
データの結合(マージ)
2 つのデータフレームをマージ(併合)する場合は関数 merge() を用いる.関数 merge() は 2 つのデータフレームの両方にある列データ(この場合は ID )で紐付けをしてデータをマージ(併合)する.このとき,引数 all に何も指定しない場合は ID が共通しているデータのみを残して併合,T を指定した場合は全てのデータが併合される.また,引数 all.x と all.y でそれぞれのデータフレームにおいて,どちらのデータを残すか否か(all.x : 左結合,all.y : 右結合)を指定することが出来る.
merge(D1, D2) ID H W 1 A 158 51 2 E 166 55 ( D <- merge(D1, D2, all=T) ) ID H W 1 A 158 51 2 C 177 NA 3 E 166 55 4 B NA 55 5 D NA 57 |
引数 by で,2 つのデータフレームを紐付けする列名(この場合は ID )を指定することも出来る.また,異なる列名で 2 つのデータフレームを紐付けする場合は,引数 by.x と by.y で指定すればよい.
列名は by.x で指定した名前となる.また,引数 sort に F を指定して自動的に整列するのを制御することも出来る.引数 by や by.x と by.y に名前のベクトルを指定すれば良い(例:merge(D1, D2, by.x=names(D1), by.y=names(D2), all=T)).
|
データフレーム D3
|
データの整列(ソート)
ソートを行う場合は,まず関数 order(昇順の対象となる列) で順番を作成し,それを使ってデータフレームにアクセスすればよい.例として,先ほどマージしたデータフレーム D の W についてソートを行ってみる.
sortlist <- order(D$W) ( D4 <- D[sortlist,] ) ID H W 1 A 158 51 3 E 166 55 4 B NA 55 5 D NA 57 2 C 177 NA |
ソート後は行番号がバラバラになる.行番号ラベルを変更する場合は以下のようにする.
rownames(D4) <- c(1:nrow(D4)) D4 ID H W 1 A 158 51 2 E 166 55 ........... |
複数の列に対してソートを行う場合は関数 order(1番目の列, pmax(1番目の列, 2番目の列)) として順番を作成し,それを使ってデータフレームにアクセスすればよい.
sortlist <- order(D$W, pmax(D$W, D$H)) D[sortlist,] # W を昇順に並べる # W で同じ値がある場合は H の小さい方を上にする ID H W 1 A 158 51 3 E 166 55 4 B NA 55 5 D NA 57 2 C 177 NA sortlist <- order(D$W, pmax(D$W, D$ID)) D[sortlist,] # W を昇順に並べる # W で同じ値がある場合は ID の小さい方を上にする ID H W 1 A 158 51 4 B NA 55 3 E 166 55 5 D NA 57 2 C 177 NA |
データの加工と抽出に関する関数一覧
データ加工に関する関数の一覧はこちら(以下に出てくる x はデータフレームとする).
コマンド |
機能 |
head(x, n=a) |
先頭から a 行だけ抽出する.関数 tail(x, n=b) で末尾から b 行だけ抽出する. |
na.omit(x) |
NA を含む行を削除する.関数 na.exclude() も似た様な関数である. |
transform(x, y=値) |
データフレーム x に新たな列 y を追加する. |
x[sapply(x, 論理ベクトル)] |
論理ベクトルが TRUE となっている行にのみアクセスする.例えば x[sapply(x, is.numeric)] ならば数値データにのみアクセスする. |
subset(x, 条件式) |
条件式に合う行のみを抽出する. |
subset(x, 条件式, ベクトル) |
ベクトルで指定した列に対し,条件式に合う行のみを抽出する. |
split(x, 列名や条件式) |
列がカテゴリーデータならば列名でデータフレームを分割する.条件式でデータフレームを分割することも出来る(例:split(x, x$w==70) ). |
by(x, x\$列名, mean) |
データ x を層別して平均を求める.mean を別の関数に変えても良い.関数 aggregate() も似た機能を持つ関数である. |
reshape(x, ...) |
データフレームを横に展開する. |
データの加工例
まず,データフレーム DF を作成する.
|
データフレーム DF
|
データフレーム DF の体重(W)の列だけを足し算したい場合は以下のように列ラベルを指定し,それごと関数 sum() に放り込んでやればよい.また,体重の単位を g(グラム)に変換する場合は,体重(W)の列を 1000 倍したものをデータフレームに代入してやればよい.
sum(DF$W) # 体重の和を求める DF$W <- DF$W * 1000 # 体重の単位を kg から g に変換する DF ID SEX H W 1 1 F 158 51000 2 2 F 162 55000 .................. |
DF に新たな変数 G を追加する場合は,関数 transform() を使うか,単に代入すればよい.
transform(DF, G=DF$W * 1000 ) # DF$G <- DF$W * 1000 でも可 ID SEX H W G 1 1 F 158 51 51000 2 2 F 162 55 55000 .................... |
条件に当てはまる行のみに処理を施す場合は,関数 ifelse(条件式, TRUE の場合に返す値, FALSE の場合に返す値) を用いる.
DF$W <- ifelse(DF$SEX=="F", NA, DF$W) # 女性の体重を隠す(NAに) DF ID SEX H W 1 1 F 158 NA 2 2 F 162 NA 3 3 M 177 72 ............... |
条件に当てはまるものだけを抽出する場合は,条件式をデータフレームの [ ] などで指定すればよい.
cond <- (DF$H >= 170) # 身長(H)が 170cm 以上の人を抽出 DF[cond,] ID SEX H W 3 3 M 177 72 4 4 M 173 57 |
関数 subset() や関数 sapply() を用いても,条件に当てはまるものだけを抽出することが出来る.
subset(DF, ID>3) # ID > 3 となる行 ID SEX H W 4 4 M 173 57 5 5 M 166 64 subset(DF, ID>3, c(ID, SEX)) # ID > 3 となる "ID" と "SEX" のみ ID SEX 4 4 M 5 5 M |
整数データをカテゴリ変数と認識させる場合は関数 as.factor() で変換すればよく,「順序変数宣言を行う場合は as.ordered(A$id)」「量的変数宣言を行う場合は as.single(A$w)」とすればよい.
DF$ID <- as.factor(DF$ID) # データを見ても変換されたかどうかが分からない DF[sapply(DF, is.numeric)] # 数値変数だけを選択 H W 1 158 NA 2 162 NA ........ |
ID を固定し,SEX(性別)で場合分けしてデータを横に展開する場合は関数 reshape() を用いる.
reshape(DF, timevar="SEX", idvar="ID", direction="wide") ID H.F W.F H.M W.M # H.F:女性の身長,W.F:女性の体重,H.M:男性の体重,W.M:男性の体重 1 1 158 51 NA NA 2 2 162 55 NA NA 3 3 NA NA 177 72 4 4 NA NA 173 57 5 5 NA NA 166 64 |
データフレームの出力
read.table() に対して関数 write.table() や write() で実現できる.例えば以下の様な 5 行 3 列のデータが入ったファイル data11.txt が( C:/ に)あったとする.このデータ data11.txt を関数 read.table() で読み込んで,関数 write.table(データフレーム名, "出力するファイルのパス") でファイル output.txt に出力してみる.write.table(x,"C:/output.txt") だけでは(quote=F にしないと)要素に "" がついてしまう.
|
data11.txt
|
データフレームを出力する際は write.table() が使いやすいが,リストをファイルに出力する場合は write(リスト名, "出力するファイルのパス") が使いやすい.それぞれの関数の書式は以下のようになっている.「出力するファイルのパス」は,空文字列 "" なら標準出力に出力される.
- write(リスト名, "出力するファイルのパス", append = T, ncolumns = 一行の要素の数)
- write.table(データフレーム名, "出力するファイルのパス", append=T, quote=F, col.names=F)
関数 write() について使い方の例を以下に挙げる.
x <- matrix(1:8, ncol=2) # 4 * 2 の行列 write(x, file="data12.txt") # ファイル data12.txt に書き出し scan("data12.txt") # scan 関数で再読み込み(結果はベクトル) Read 8 items [1] 1 2 3 4 5 6 7 8 y <- matrix(scan("data12.txt"), ncol=4) # また行列に変換 Read 8 items y [,1] [,2] [,3] [,4] [1,] 1 3 5 7 [2,] 2 4 6 8 |
区切り文字を付けたデータの出力
リストに入ったデータを,例えばカンマ ,で区切ってファイルに出力する場合,まず,「データ ,カンマ,データ ,カンマ,・・・」 というリストを作っておいて,次に関数 write() で 1 行ごとにファイルに出力すればよい.
|
data14.txt
|
また,関数 writeLines(paste(データ), sep=",") とすれば区切り文字を綿密に指定してファイルに書き込みを行うことが出来る.この際,明示的に改行\n を指定しないと改行されない.
|
data15.txt
|
出力したファイルを EXCEL で読み込む: カンマ区切りで出力し,拡張子を【.csv】として保存する
データの tex ・ html 命令への変換
以下のデータ x を,LaTeX の表を出力する命令に書き直す場合は以下のようにする.
library(xtable) x <- matrix(1:24,4,6) x [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 5 9 13 17 21 [2,] 2 6 10 14 18 22 [3,] 3 7 11 15 19 23 [4,] 4 8 12 16 20 24 mytable <- xtable(x) print(mytable) % latex table generated in R 1.8.1 by xtable 1.2-1 package % Mon Feb 02 00:44:46 2004 \begin{table}[ht] \begin{center} \begin{tabular}{rrlllr} \hline & grade & sex & disadvg & ethnicty & tlimth \\ \hline 1 & 6 & M & YES & HISPANIC & 43 \\ 2 & 7 & M & NO & BLACK & 88 \\ 3 & 5 & F & YES & HISPANIC & 34 \\ 4 & 3 & M & YES & HISPANIC & 65 \\ 5 & 8 & M & YES & WHITE & 75 \\ 6 & 5 & M & NO & BLACK & 74 \\ 7 & 8 & F & YES & HISPANIC & 72 \\ 8 & 4 & M & YES & BLACK & 79 \\ 9 & 6 & M & NO & WHITE & 88 \\ 10 & 7 & M & YES & HISPANIC & 87 \\ 11 & 3 & M & NO & WHITE & 79 \\ 12 & 6 & F & NO & WHITE & 84 \\ 13 & 8 & M & NO & WHITE & 90 \\ 14 & 5 & M & NO & WHITE & 73 \\ 15 & 8 & F & NO & WHITE & 72 \\ 16 & 6 & F & NO & BLACK & 82 \\ 17 & 4 & M & NO & WHITE & 69 \\ 18 & 3 & F & YES & HISPANIC & 17 \\ 19 & 3 & M & NO & HISPANIC & 37 \\ 20 & 5 & M & NO & WHITE & 70 \\ \hline \end{tabular} \end{center} \end{table} |
このデータ x を,html の表を出力する命令に書き直す場合は以下のようにする.
print(mytable,type="html") |
他にもパッケージ Hmisc 中の関数 latex() がある.
関数 scan() について
関数 scan(ファイルのパス) を用いると,ファイルからベクトルとしてデータを読み込むことが出来き,大規模のデータセットをRに読み込むのに適している. 最も簡単にデータ(例えば右下の data07.txt )を読み込むには以下のようにすれば良い. 以下では全 6 行のうち 1 行目を読み飛ばして x にデータ (データフレーム) を読み込んでいる.
|
data07.txt
|
関数 scan() で読み込んだデータはベクトルデータである.これを行列に変換する場合は以下のようにすればよい.
x <- matrix( scan("data07.txt", skip=1, nlines=6), 5, byrow=T) |
以下に関数 scan() の引数を,関数 read.table() の引数と併せて紹介する.
read.table() の引数 |
|
scan() の引数 |
||
引数 |
機能 |
引数 |
機能 |
|
sep = "" |
データとデータの区切り文字を指定する. |
sep = "" |
データとデータの区切り文字を指定する. |
|
skip = 0 |
最初の行 から読み飛ばす行数を指定する.指定しない場合はファイルの 1 行目から読む. |
skip = 0 |
最初の行 から読み飛ばす行数を指定する.指定しない場合はファイルの 1 行目から読む. |
|
nrows = -1 |
何行目まで読むかを指定する .指定しない場合(負の値の場合)はファイルの終わりまで読む). |
nlines |
何行目まで読むかを指定する .指定しない場合はファイルの終わりまで読む). |
|
header = F |
「1行目は列名が書かれている」か否かを指定する.列名が書かれている場合で,F を指定すると不具合が生じる. |
what |
データのタイプを指定する |
|
comment.char |
コメント行を表す記号(デフォルトは \# )を指定する. |
nmax = -1 |
データを読み込む個数を指定する.nmax について,what にリストが指定されていたらリストを読み込む個数を指定することが出来る. |
|
その他 |
quote = "'",row.names, col.names などがある. |
その他 |
quote = "",n = -1,na.strings = "NA" などがある. |
Rを経由したファイル変換
library(foreign)を実行し、他のソフトにより書き出したファイルを読む。
library(foreign) > x<-read.dta("wtf65.dta") 読み込み > write.csv(x,"wtf65.csv") 書き出し |
foreignはこれ以外にも、
コマンド |
機能 |
read.arff |
Attribute-Relation File Format (ARFF)ファイルの読み込み |
read.dbf |
dbf形式のファイルの読み込み |
read.epiinfo |
Epiファイルの読み込み |
read.mtp |
Minitabファイルの読み込み |
read.octave |
Octaveファイルの読み込み |
read.S |
S Version 3ファイルの読み込み |
read.spss |
SPSSファイルの読み込み |
read.ssd |
SASファイルの読み込み |
read.sysdat |
Systatファイルの読み込み |
read.xport |
SAS XPORT形式のファイルの読み込み |
SASのファイルは、SAS7BDATのライブラリーで上と同様にできるようです。
Back to R