46. 落穂ひろい


組み込みデータにアクセスする方法

R には多数のサンプル・データセットが用意されている.これは関数 data() を用いることで一覧を見ることが出来る.

 
 data()                       # 全てのデータセットを表示
 data(package ="base")        # base パッケージのデータセットを表示
 data(USArrests, "VADeaths")  # データ USArrests, VADeaths をロード
 help(USArrests)              # データ USArrests のヘルプを見る 

もしデータがライブラリの中に入っている場合は,先にライブラリを呼び出す必要がある.

 
 library(nls)                 # ライブラリ nls の呼び出し
 data(Puromycin)              # データ `Puromycin' の呼び出し 

attach() と detach()

データフレームの要素を参照するときは『データフレーム名$要素のグループ』と $ を用いて参照する.しかしデータフレーム名をいちいち指定するのは面倒である.データフレームの成分を,リスト名を明示的に指定することなしに指定できれば楽である.

例えば myframe が myframe$u ,myframe$v ,myframe$w を持つデータフレームであるとする.このとき関数 attach(myframe) を実行することで,myframe$ を付けすに u,v,w だけで変数にアクセスすることが出来るようになる.ただし,直前までに u という名前の変数を使っていると不具合が出るので注意が必要である.

 
 u <- 1:5;  v <- rnorm(5);  w <- u*v
 myframe <- data.frame(u=u, v=v, w=w)
 attach(myframe)
 w               # attach() を実行することで列名 w だけでデータにアクセス出来る

[1]  0.166959  1.676896  1.435630 -3.024536  1.859002

関数 attach() は組み込みデータを使う際にも有用である.

 
 data(sleep)     # R に標準で用意されているデータ(W.S.Gosset (Student) の睡眠薬の比較データ)
 attach(sleep)
 extra           # attach() を実行することで extra だけでデータにアクセス出来る

 [1]  0.7 -1.6 -0.2 -1.2 -0.1  3.4  3.7  0.8  0.0  2.0  1.9  0.8
[13]  1.1  0.1 -0.1  4.4  5.5  1.6  4.6  3.4

関数 attach(myframe) を実行することで,リストの成分をリスト名を明示的に指定することなしに指定することも出来る.

 
 myframe <- list(c("a","b","c"), c(1:3), c(1.5,3.2,-0.8))
 names(myframe) <- c("u", "v", "w")
 attach(myframe)          # attach() を実行することで u だけでデータにアクセス出来る
 u

[1] "a" "b" "c"

データフレームを検索リストから外すには関数 detach() を用いればよい.これ以後,myframe$u の値を参照するには, u だけを入力しても参照することは出来ない.関数などの繰り返し文中等で同じデータフレームを何度も attach する場合は,一まとまりの処理が終って不要になったらこまめに detach() (例:on.exit(detach(sleep) ) を関数本体に入れる) しないと,処理時間が次第に遅くなるとので注意.

 
 search()         # どんなリストやデータフレームがあるかを調べる
 detach(sleep)    # sleep を外す

処理時間の問題が気になる場合は,attach() に代わる関数 with() を用いる.with() はデータフレームなどから専用の環境を作ってその中で作業を行う.結果として attach() せずに成分を参照することが出来,with() の作業が終了すればこの環境もなくなるので,変数名の衝突などの不具合が起きない.

 
 data(sleep)
 with(sleep, {                  # sleep から専用の環境を作ってその中で F 検定を行う
   x <- extra[group==1]
   y <- extra[group==2]
   var.test(x, y)
 })
        F test to compare two variances

data:  x and y 
F = 0.7983, num df = 9, denom df = 9, p-value = 0.7427
alternative hypothesis: true ratio of variances is not equal to 1 
95 percent confidence interval:
 0.198297 3.214123 
sample estimates:
ratio of variances 
         0.7983426 

欠損の扱い

手入力でデータフレームを作成する場合で欠損が含まれているデータを読み込む場合は,ベクトル中の欠損部分を NA としておけば,該当部分に欠損値(NA)が入る.

 
 sex <- c("F",NA,"M"); height <- c(158,162,NA); weight <- c(51,55,72)
 ( x <- data.frame(SEX=sex, HEIGHT=height, WEIGHT=weight) )

   SEX HEIGHT WEIGHT
1    F    158     51
2 <NA>    162     55
3    M     NA     72

ファイルからデータを読み込む場合で欠損が含まれているデータを読み込む場合は,data06.txt のように,データ間がコンマ( ,)で区切られている方が処理しやすい.この場合,単に欠損部分を空白にしておけば,該当部分に欠損値(NA)が入る.

 
 ( x <- read.table("data06.txt", header=T, sep=",") )

  sex height weight
1   F    158     51
2   F    162     55
3   M     NA     72
4   M    173     57
5   M    166     64

 data06.txt

 
sex,height,weight
F,158,51
F,162,55
M,   ,72
M,173,57
M,166,64

サンプルデータの作成:関数 expand.grid()

関数 expand.grid(引数1=ベクトル1,引数2=ベクトル2,・・・) を用いることで,引数に指定した因子全ての組み合わせから成るデータフレームを作ることができる.

 
 expand.grid(height = seq(150, 170, 10), weight = c(50, 60), sex = c("Male","Female"))

   height weight    sex
1     150     50   Male
2     160     50   Male
3     170     50   Male
4     150     60   Male
5     160     60   Male
6     170     60   Male
7     150     50 Female
8     160     50 Female
9     170     50 Female
10    150     60 Female
11    160     60 Female
12    170     60 Female

関数 scan() について

関数 scan(ファイルのパス) を用いると,ファイルからベクトルとしてデータを読み込むことが出来る.最も簡単にデータ(例えば右下の data07.txt )を読み込むには以下のようにすれば良い.以下では全 6 行のうち 1 行目を読み飛ばして x にデータ (データフレーム) を読み込んでいる.

 
 x <- scan("data07.txt", skip=1, nlines=6)

Read 20 items

 x

 [1] 171.0  62.6  23.0   1.0 158.0  49.8
 [7]  25.0   0.0 163.0  68.7  42.0   1.0
[13] 178.0  75.4  33.0   1.0 163.0  55.7 
[19]  28.0   0.0

 data07.txt

 
# data07.txt
171 62.6 23 1
158 49.8 25 0
163 68.7 42 1
178 75.4 33 1
163 55.7 28 0

R でファイルからデータを読み込むのは関数 read.table() の方が便利であると思われるが,scan() よりもメモリを多く必要として実行速度も scan() より劣る.本格的に多くのデータを取り込む場合,複雑な規則でデータの読み込みを行いたい場合には scan() を使用した方が良い.また,データの出力 は,関数 read.table() に対して関数 write.table() や write() で実現できる.

関数 scan() で読み込んだデータはベクトルデータである.これを行列に変換する場合は以下のようにすればよい.

 
 x <- matrix( scan("data07.txt", skip=1, nlines=6), 5, byrow=T)

list(ダミーのリスト)を用いると,5 行 4 列のデータとして読み込むことが出来る上,該当する列の "" にラベルを入れることでラベルをつけることが出来る.以下はデータの型が全て文字型であると R に指定していることになる.

 
 x <- scan("data07.txt", list("",weight="","",sex=""),skip=1, nlines=6)

Read 5 records

 x

[[1]]
[1] "171" "158" "163" "178" "163"
$weight
[1] "62.6" "49.8" "68.7" "75.4" "55.7"
[[3]]
[1] "23" "25" "42" "33" "28"
$sex
[1] "1" "0" "1" "1" "0"

データの型を数値であると指定する場合は ラベル = 0  (または ラベル = 1 など) とすればよい.以下では sex は性別なので文字型,それ以外は数値として読み込んでいる.

 
 x <- scan("data07.txt", list(h=0,w=1,a=0,s=""), skip=1)

Read5 records

 x

$h
[1] 171 158 163 178 163
$w
[1] 62.6 49.8 68.7 75.4 55.7
$a
[1] 23 25 42 33 28
$s
[1] "1" "0" "1" "1" "0"

このときラベルを付けない場合は R の方で勝手にラベルをつける.以下では sex は性別なので文字型,それ以外は数値として読み込んでいる. あとは read.table() で読み込んだのと同様にしてアクセスすることが出来る.また,edit() を使って編集することも出来る.

 
 x$h <- x$h/100

以下に関数 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" などがある.

関数 scan() の使用上の注意(1)

関数 scan() で読み込む際,最後は改行文字で終わっていなければいけない.例えば,データが 2 行ある場合は,2 行目の最後で必ず改行しないと警告が出る.

 
 x <- scan("data08.txt", sep=",")

Read 10 items

 x

 [1]  1  2  3  4  5  6  7  8  9 10

 data08.txt

 
1,2,3,4,5
6,7,8,9,10

行の最後は改行のみとすること.例えば data09.txt のように区切り文字がカンマ( ,)の場合で,行の最後にカンマが入っている場合は,結果に不要な欠損値が入ってしまう.

 
 x <- scan("data09.txt", sep=",")

Read 11 items

 x

 [1]  1  2  3  4  5 NA  6  7  8  9 10

 data09.txt

1,2,3,4,5,
6,7,8,9,10

 実際に読み込まれたデータ

1,2,3,4,5,
6,7,8,9,10,

関数 scan() の使用上の注意(2)