読者です 読者をやめる 読者になる 読者になる

疫学と医療統計学と遺伝学と時々、大学院生活

疫学を専門とする大学院生の研究に関する備忘録的ページ。

R for beginners vol.2 「データの入出力とサブセット」

R for beginners R programming

今回は前週に引き続き、第2回「Rのデータセットの扱い方(入力と出力及びサブセット)」に移る。

R for beginners vol.1 「Rの紹介と基本的なコマンド」
jojoshin.hatenablog.com

【今回の狙い】データの取り込み、書き出し方法やデータセットの整理ができるようになる

1. データのインプット

実際のデータ解析では、.csvや.txt、.xlsxをインプットして、解析に用いる。そのため、このコマンドはデータ解析の初歩であり、最も肝心であると言える。

1-1. csvファイルの読み込み(個人的にはこれが最も簡単で推奨したい)

#csvデータのインプットはこの一行で完了する。
#read.csvが「csvファイルを読みますよ」と言う宣言で、その中身が「何をどうする?」の部分にあたる記述
#この場合は、ファイル名の他に、headerという「一列目に列名があるか否か」を示す記述や、sepという「データが何で区切られて入力されている」を示す記述があるのが見てとれる。
#この他にも、skip=xという「始めのx行は飛ばして、データを読み込む」ことを指示する記述もある。
dt.csv <- read.csv("dt.csv", header=T, sep=",")

前回の復習(vol.1)を参考にして、このデータの中身を軽く見ると、

str(dt.csv)
## 'data.frame':	1000 obs. of  8 variables:
##  $ age    : int  35 45 41 44 68 42 51 64 46 63 ...
##  $ gender : Factor w/ 2 levels "Female","Male": 2 1 1 1 1 2 1 1 2 2 ...
##  $ height : num  171 155 152 148 152 ...
##  $ weight : num  73.5 41.5 43.1 40.3 39.6 ...
##  $ BMI    : num  25.3 17.3 18.5 18.4 17 ...
##  $ alcohol: Factor w/ 3 levels "high","low","middle": 3 2 2 3 2 3 2 1 3 1 ...
##  $ BMI01  : int  1 0 0 0 0 1 0 0 0 1 ...
## $ ID     : int  1 2 3 4 5 6 7 8 9 10 ...

names(dt.csv)
## [1] "age"     "gender"  "height"  "weight"  "BMI"     "alcohol" "BMI01"  
## [8] "ID" 

head(dt.csv)
##   age gender   height   weight      BMI alcohol BMI01 ID
## 1  35   Male 170.5088 73.51593 25.28644  middle     1  1
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 6  42   Male 174.9575 76.66370 25.04522  middle     1  6

1-2. xlsxファイルの読み込み(パッケージ"openxlsx"が必要)
library(x)の前にパッケージがインストールされていない場合は、install.packages("x")でインストール指定から実行する

library(openxlsx)
dt.xlsx <- read.xlsx("dt.xlsx")
str(dt.xlsx)
## 'data.frame':	1000 obs. of  8 variables:
##  $ age    : num  35 45 41 44 68 42 51 64 46 63 ...
##  $ gender : chr  "Male" "Female" "Female" "Female" ...
##  $ height : num  171 155 152 148 152 ...
##  $ weight : num  73.5 41.5 43.1 40.3 39.6 ...
##  $ BMI    : num  25.3 17.3 18.5 18.4 17 ...
##  $ alcohol: chr  "middle" "low" "low" "middle" ...
##  $ BMI01  : num  1 0 0 0 0 1 0 0 0 1 ...
##  $ ID     : num  1 2 3 4 5 6 7 8 9 10 ...

head(dt.xlsx)
##   age gender   height   weight      BMI alcohol BMI01 ID
## 1  35   Male 170.5088 73.51593 25.28644  middle     1  1
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 6  42   Male 174.9575 76.66370 25.04522  middle     1  6

1-3. txtファイル(タブ区切り)の読み込み

#sepが"\t"に変わっていることに注目
dt.txt <- read.table("dt.txt", header=T, sep="\t")
str(dt.txt)
## 'data.frame':	1000 obs. of  8 variables:
##  $ age    : int  35 45 41 44 68 42 51 64 46 63 ...
##  $ gender : Factor w/ 2 levels "Female","Male": 2 1 1 1 1 2 1 1 2 2 ...
##  $ height : num  171 155 152 148 152 ...
##  $ weight : num  73.5 41.5 43.1 40.3 39.6 ...
##  $ BMI    : num  25.3 17.3 18.5 18.4 17 ...
##  $ alcohol: Factor w/ 3 levels "high","low","middle": 3 2 2 3 2 3 2 1 3 1 ...
##  $ BMI01  : int  1 0 0 0 0 1 0 0 0 1 ...
## $ ID     : int  1 2 3 4 5 6 7 8 9 10 ...

head(dt.txt)
##   age gender   height   weight      BMI alcohol BMI01 ID
## 1  35   Male 170.5088 73.51593 25.28644  middle     1  1
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 6  42   Male 174.9575 76.66370 25.04522  middle     1  6

1'. 補足
今回のデータセットはどれもこのR projectが動いているworking directoryに置いてあるデータであったが、そうでない場合(すなわち他のフォルダにデータが存在する場合)、どのようにデータを読み込むか述べる。

#今のworking directoryを表示する
getwd()
## [1] "/Users/RF/Desktop/Introduction to R"

ここ以外にあるデータセットの読み込みは下記の通り、ファイル名のところにパスを書く。

dt.csv2 <- read.csv("/Users/RF/Desktop/dt.csv", header=T, sep=",")
2. データフレームの作成とそのアウトプット
age <- c(31, 39, 44, 20)
sex <- factor(c("F", "M", "F", "M"))
BMI <- c(22.4, 29.0, 21.7, 19.0)
mogi <- data.frame(age, sex, BMI)
mogi
##   age sex  BMI
## 1  31   F 22.4
## 2  39   M 29.0
## 3  44   F 21.7
## 4  20   M 19.0

#今回はこのmogiを"data.csv"として書き出す(行番号の出力(row.names)はFALSEに指定した)
write.csv(mogi, "data.csv", row.names=F)
3. logical statementを使用したデータのサブセット

3-1. logical statementの仕組みを理解しよう

#1〜4の整数値を作る
x <- 1:4
#x=3であるかを確認する(r内では=を==と記述する)
x==3
## [1] FALSE FALSE  TRUE FALSE

#今度はx=3でないことを確認する。(でないという否定は"!="と記述する)
x!=3
## [1]  TRUE  TRUE FALSE  TRUE

#文字列でも同様
y <- c("dog", "cat", "dog", "cat", "cat", "dog", "cat", "cat", "cat")
y=="cat"
## [1] FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE

y!="cat"
## [1]  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE

3-2. 実際のデータでの使い方を試してみよう(dtをサブセットして、dtwomenという女性のデータセットを作成する)

dt <- read.csv("dt.csv", header=T, sep=",")
head(dt)
##   age gender   height   weight      BMI alcohol BMI01 ID
## 1  35   Male 170.5088 73.51593 25.28644  middle     1  1
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 6  42   Male 174.9575 76.66370 25.04522  middle     1  6

#性別の人数比を表示する
table(dt$gender)

## Female   Male 
##    580    420 

#logical statementで女性であるか否かを表示する
head(dt$gender=="Female")
## [1] FALSE  TRUE  TRUE  TRUE  TRUE FALSE

#それをベクトル化する
women <- dt$gender=="Female"

#FemaleがTRUEかFALSEかそれぞれ何人いるかを表示する
table(women)
## women
## FALSE  TRUE 
##  420   580 

#FemaleがTRUEの行だけ選び出す
#新しいデータセットになるので、指定する名前に注意すること(rは上書き方式であることに留意)
dtwomen1 <- dt[women,]

#できたデータdtwomenの先頭6行を表示する(dtでは1や6番目のデータは男性であったが、ここでは消えていることを確認する)
head(dtwomen1)
##   age gender   height   weight      BMI alcohol BMI01 ID
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 7  51 Female 147.4509 53.99585 24.83509     low     0  7
## 8  64 Female 153.9943 49.12924 20.71718    high     0  8

dim(dtwomen1)
## [1] 580   8
4. whichを使用したデータのサブセット

4-1. whichの仕組みを理解しよう

x <- c(1, 2, 30, 5, 13)

#whichではその条件に該当する要素の番号(データでいえば行番号)を返す
which(x==5)
## [1] 4

#文字列も同様
y <- c("rice", "bread", "rice", "bread")
which(y=="bread")
## [1] 2 4

4-2. 実際のデータで使用してみよう。(3.と同様のデータを使用する)

#dt$genderの中でFemaleである行番号をwomenというベクトルにする
women <- which(dt$gender=="Female")

#FemaleがTRUEの行だけ選び出す
dtwomen2 <- dt[women,]

#できたデータdtwomenの先頭6行を表示する
head(dtwomen2)
##   age gender   height   weight      BMI alcohol BMI01 ID
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 7  51 Female 147.4509 53.99585 24.83509     low     0  7
## 8  64 Female 153.9943 49.12924 20.71718    high     0  8
5. subsetを使用したデータのサブセット(めちゃめちゃ簡単)
dtwomen3 <- subset(dt, gender=="Female")
head(dtwomen3)
##   age gender   height   weight      BMI alcohol BMI01 ID
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 7  51 Female 147.4509 53.99585 24.83509     low     0  7
## 8  64 Female 153.9943 49.12924 20.71718    high     0  8
6. and/orを使用した複数の条件を用いたサブセット

andは日本語で言えば『かつ』であり、"&"を使用して表現する。
orは日本語で言えば『もしくは』であり、"|"を使用して表現する。

6-1. and/orを使用する。

x
## [1]  1  2 30  5 13

#xが『2よりも大きい、かつ30以下』
#注意: 2 < x <= 30 という記述はできないので、&を使用し分割して記述します
x>2 & x<=30
## [1] FALSE FALSE  TRUE  TRUE  TRUE

#xが『2未満、もしくは30以上』
x<2 | x>=30
##  [1]  TRUE FALSE  TRUE FALSE FALSE

6-2. 複数の条件式を使用して、データのサブセットする(例えば、女性で170cm以上の人を選びたいとする)

#ちなみにその人数を前もって調べると、、、
length(which(dt$gender=="Female" & dt$height >= 170))
## [1] 4

6-2-1. logical statementで実行してみる。

women1701 <- dt$gender=="Female" & dt$height >= 170
dtwomen1701 <- dt[women1701, ]
head(dtwomen1701)
##     age gender   height   weight      BMI alcohol BMI01  ID
## 265  64 Female 175.7361 38.68214 12.52532  middle     0 265
## 274  67 Female 171.0478 51.23359 17.51137     low     0 274
## 510  44 Female 173.6013 41.44780 13.75294     low     0 510
## 875  56 Female 170.6064 40.89102 14.04873     low     0 875

6-2-2. whichを使用してみる。

women1702 <- which(dt$gender=="Female" & dt$height >= 170)
dtwomen1702 <- dt[women1702, ]
head(dtwomen1702)
##     age gender   height   weight      BMI alcohol BMI01  ID
## 265  64 Female 175.7361 38.68214 12.52532  middle     0 265
## 274  67 Female 171.0478 51.23359 17.51137     low     0 274
## 510  44 Female 173.6013 41.44780 13.75294     low     0 510
## 875  56 Female 170.6064 40.89102 14.04873     low     0 875

6-2-3. subsetを使用してみる

dtwomen1703 <- subset(dt, gender=="Female" & height >= 170)
head(dtwomen1703)
##     age gender   height   weight      BMI alcohol BMI01  ID
## 265  64 Female 175.7361 38.68214 12.52532  middle     0 265
## 274  67 Female 171.0478 51.23359 17.51137     low     0 274
## 510  44 Female 173.6013 41.44780 13.75294     low     0 510
## 875  56 Female 170.6064 40.89102 14.04873     low     0 875

6-2-4. ここで「女性かつ170cm以上の人」以外のデータを選びたい時には、、、

women170 <- which(dt$gender=="Female" & dt$height >= 170)

#whichで指定した「女性かつ170cm以上の人」(women170)をマイナスで除外するという考え方
dtother <- dt[-women170,]

head(dtother)
  age gender   height   weight      BMI alcohol BMI01 ID
## 1  35   Male 170.5088 73.51593 25.28644  middle     1  1
## 2  45 Female 154.8704 41.49381 17.30001     low     0  2
## 3  41 Female 152.4852 43.05607 18.51736     low     0  3
## 4  44 Female 148.0986 40.32888 18.38713  middle     0  4
## 5  68 Female 152.3321 39.55690 17.04665     low     0  5
## 6  42   Male 174.9575 76.66370 25.04522  middle     1  6

dim(dtother)
## [1] 996   8
練習問題(全14問)

PART 1(6問)
まず、ネットからモニュメントのデータをインストールする.
https://data.baltimorecity.gov/Culture-Arts/Monuments/cpxf-kxp3にアクセスする.
Export –> Download –> Download As: CSVを選択する
ダウンロードしたデータをR studioのワーキングディレクトリに入れる。

0. データを読み込み,'mdt'と名付けよ.
1. "Location.1"の列名を"location"に変更せよ.(難問)
2. ボルティモアにはいくつのmonument(モニュメント)があるか答えよ.(前回の復習)
3. (a) zip codes, (b) neighborhoods, (c) council districtsおよび(d) police districtsにはそれぞれどんな要素があるか、またそれらは合計で何種類あるか.(前回の復習)
4. (a) "Downtown"と(b) "Johns Hopkins Homewood"にZip codeはそれぞれいくつあるか答えよ.(ヒント:データのサブセットを使用すると簡単)
5. 正確な住所のある/ないモニュメントはそれぞれいくつあるか答えよ.(ヒント:住所のないのはどうやって表現されているかデータを見て確認する)

PART 2(全8問)
0. サイト(https://data.baltimorecity.gov/Transportation/Bike-Lanes/xzfj-gyms)からCSV形式でデータをダウンロードし、データを読み込む
1. 整備された年("dateInstalled")が"0"となっているデータを除外し、新たなデータセット'bike2'を作成せよ.
2. ボルチモアにはいくつのバイクのレーンがあるか答えよ.("numLanes"を使用して答えよ.)
3. ボルチモアにあるバイクレーンの長さ("length")の総長は何mか答えよ.(ヒント:この長さはフィートで記載されており、1フィートは0.3048メートルに換算できる. )
4. ボルチモアにあるバイクレーンの1レーンあたりの平均の長さ("length")は何mか答えよ.(Q2と3を利用せよ.)
5. 何種類のバイクレーン("type"を使用)があるか答えよ(注意:0レーンのtypeについては考えないものとする).さらに最も多いのはどのタイプのレーンか答えよ.
6. バイクレーンが整備された始めたのは何年からか(開始年)答えよ.また、最も多くのバイクレーンが整備されたのは何年か.
7. 2010年に整備された'BKIELANE'(これはtypeの列内にある種類のこと)の平均の長さは何mか答えよ.(ヒント:まずは二つの条件でサブセットして、そのあとにQ4同様に平均を求める.)

今回は以上とする。
次回も5/26までにはUPする(内容はデータクリーニングとデータの編集)。


20160518
RF