9 データハンドリング
ここまで、ggplot2を使ったデータの可視化を見てきた。ただし、ggplot2で作図をする際、大きな前提条件がある。それは、データを行列(データフレームもしくはtibbleと呼ばれる形式)で用意しなければいけないというものである。つまり、変数を列に、観測値を行に取るようなデータ構造にあらかじめ整形しなければならないということである。
たとえば、今まで使ってきたmtcars
、faithful
のデータ構造を改めて見てみよう。
head(mtcars) # 先頭6行
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
head(faithful) # 先頭6行
## eruptions waiting
## 1 3.600 79
## 2 1.800 54
## 3 3.333 74
## 4 2.283 62
## 5 4.533 85
## 6 2.883 55
どちらも、列に変数名、行に観測値という構造になっている。
散布図、箱ひげ図、ヒストグラムのように、これらのデータの素値をプロットする際、データハンドリングはあまり問題にならない。しかし、実際は平均値や標準誤差のように、何かしらの統計的処理を施した値をプロットしたいこともある。また、ある1つのグループのデータだけをプロットしたいという場合もある。
可視化の際に直面する問題は、おおよそ以下の3つに大別できるだろう。
1つのグループのデータだけを抽出した上でプロットしたい(たとえば、3条件のうち統制条件だけプロットしたい、など)
素値ではなく、平均値や標準誤差などの統計量をプロットしたい
2つ以上のデータフレームを結合してプロットしたい
などである。これらの問題は、いずれもtidyverseと呼ばれるパッケージ群を使えば解決する。
9.1 tidyverse
データハンドリングに使うパッケージ群(複数のパッケージ)はtidyverseと呼ばれており、library(tidyverse)
で読み込むことができる。ちなみにggplot2もtidyverseの一部なので、自動的に読み込まれる。下のコードを実行すると色々メッセージが出るかもしれないが、気にしなくて良い。
library(tidyverse) # データハンドリング用のパッケージおよびggplot2を読み込む
この章では、主にggplot2のmpg
(自動車のデータ)を使い、データハンドリングを見ていくことにする。
9.2 抽出
9.2.1 データの値で絞り込み
データの値によって絞り込みを行いたい時がある。たとえば、mpg
であれば、manufacturer
の種類でデータを絞り込みたい(データの行単位で抽出したい)ということである。心理学の実験データで言えば、男性/女性のデータのみ抽出したいというような場面を想像してみてほしい。
このようなときは、filter(抽出条件)
を使えば良い。
mpg %>%
filter(manufacturer == "audi") # manufacturerが"audi"のものだけを抽出
## # A tibble: 18 x 11
## manufacturer model displ year cyl trans drv cty hwy
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int>
## 1 audi a4 1.8 1999 4 auto(l5) f 18 29
## 2 audi a4 1.8 1999 4 manual(m5) f 21 29
## 3 audi a4 2 2008 4 manual(m6) f 20 31
## 4 audi a4 2 2008 4 auto(av) f 21 30
## 5 audi a4 2.8 1999 6 auto(l5) f 16 26
## 6 audi a4 2.8 1999 6 manual(m5) f 18 26
## 7 audi a4 3.1 2008 6 auto(av) f 18 27
## 8 audi a4 quattro 1.8 1999 4 manual(m5) 4 18 26
## 9 audi a4 quattro 1.8 1999 4 auto(l5) 4 16 25
## 10 audi a4 quattro 2 2008 4 manual(m6) 4 20 28
## 11 audi a4 quattro 2 2008 4 auto(s6) 4 19 27
## 12 audi a4 quattro 2.8 1999 6 auto(l5) 4 15 25
## 13 audi a4 quattro 2.8 1999 6 manual(m5) 4 17 25
## 14 audi a4 quattro 3.1 2008 6 auto(s6) 4 17 25
## 15 audi a4 quattro 3.1 2008 6 manual(m6) 4 15 25
## 16 audi a6 quattro 2.8 1999 6 auto(l5) 4 15 24
## 17 audi a6 quattro 3.1 2008 6 auto(s6) 4 17 25
## 18 audi a6 quattro 4.2 2008 8 auto(s6) 4 16 23
## fl class
## <chr> <chr>
## 1 p compact
## 2 p compact
## 3 p compact
## 4 p compact
## 5 p compact
## 6 p compact
## 7 p compact
## 8 p compact
## 9 p compact
## 10 p compact
## 11 p compact
## 12 p compact
## 13 p compact
## 14 p compact
## 15 p compact
## 16 p midsize
## 17 p midsize
## 18 p midsize
ここで、==
は「等しい」ということを意味している。大体のプログラミング言語では、==
は「等しい」を、=
は「代入する」を意味することに注意しよう。
ちなみに、%>%
はパイプ演算子と呼ばれており、オブジェクトを次の関数の第一引数に突っ込むという操作を表している。ちょっと何を言っているのか分からないと思うが、あまり気にしなくて良い。上のコードで何がおこなわれているのか、少なくとも直観的には分かるだろう。今はそれで大丈夫である。
複数条件で絞り込むこともできる。たとえば、「manufacturer
が"audi"
」かつ「model
が"a4"
」の行を抽出したい場合は、条件を&
で繋げば良い。
mpg %>%
filter(manufacturer == "audi" & model == "a4")
## # A tibble: 7 x 11
## manufacturer model displ year cyl trans drv cty hwy fl
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr>
## 1 audi a4 1.8 1999 4 auto(l5) f 18 29 p
## 2 audi a4 1.8 1999 4 manual(m5) f 21 29 p
## 3 audi a4 2 2008 4 manual(m6) f 20 31 p
## 4 audi a4 2 2008 4 auto(av) f 21 30 p
## 5 audi a4 2.8 1999 6 auto(l5) f 16 26 p
## 6 audi a4 2.8 1999 6 manual(m5) f 18 26 p
## 7 audi a4 3.1 2008 6 auto(av) f 18 27 p
## class
## <chr>
## 1 compact
## 2 compact
## 3 compact
## 4 compact
## 5 compact
## 6 compact
## 7 compact
「manufacturer
が"audi"
」または「model
が"a4"
」の行を抽出したい場合は、条件を|
で繋げば良い。
mpg %>%
filter(manufacturer == "audi" | model == "a4")
## # A tibble: 18 x 11
## manufacturer model displ year cyl trans drv cty hwy
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int>
## 1 audi a4 1.8 1999 4 auto(l5) f 18 29
## 2 audi a4 1.8 1999 4 manual(m5) f 21 29
## 3 audi a4 2 2008 4 manual(m6) f 20 31
## 4 audi a4 2 2008 4 auto(av) f 21 30
## 5 audi a4 2.8 1999 6 auto(l5) f 16 26
## 6 audi a4 2.8 1999 6 manual(m5) f 18 26
## 7 audi a4 3.1 2008 6 auto(av) f 18 27
## 8 audi a4 quattro 1.8 1999 4 manual(m5) 4 18 26
## 9 audi a4 quattro 1.8 1999 4 auto(l5) 4 16 25
## 10 audi a4 quattro 2 2008 4 manual(m6) 4 20 28
## 11 audi a4 quattro 2 2008 4 auto(s6) 4 19 27
## 12 audi a4 quattro 2.8 1999 6 auto(l5) 4 15 25
## 13 audi a4 quattro 2.8 1999 6 manual(m5) 4 17 25
## 14 audi a4 quattro 3.1 2008 6 auto(s6) 4 17 25
## 15 audi a4 quattro 3.1 2008 6 manual(m6) 4 15 25
## 16 audi a6 quattro 2.8 1999 6 auto(l5) 4 15 24
## 17 audi a6 quattro 3.1 2008 6 auto(s6) 4 17 25
## 18 audi a6 quattro 4.2 2008 8 auto(s6) 4 16 23
## fl class
## <chr> <chr>
## 1 p compact
## 2 p compact
## 3 p compact
## 4 p compact
## 5 p compact
## 6 p compact
## 7 p compact
## 8 p compact
## 9 p compact
## 10 p compact
## 11 p compact
## 12 p compact
## 13 p compact
## 14 p compact
## 15 p compact
## 16 p midsize
## 17 p midsize
## 18 p midsize
「manufacturer
が"audi"
」でもなく「model
が"a4"
」でもない行を抽出したい場合は、条件を!()
で囲めば良い。!()
は論理値を反転させる演算子である29。
mpg %>%
filter(!(manufacturer == "audi" | model == "a4"))
## # A tibble: 216 x 11
## manufacturer model displ year cyl trans drv cty
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int>
## 1 chevrolet c1500 suburban 2wd 5.3 2008 8 auto(l4) r 14
## 2 chevrolet c1500 suburban 2wd 5.3 2008 8 auto(l4) r 11
## 3 chevrolet c1500 suburban 2wd 5.3 2008 8 auto(l4) r 14
## 4 chevrolet c1500 suburban 2wd 5.7 1999 8 auto(l4) r 13
## 5 chevrolet c1500 suburban 2wd 6 2008 8 auto(l4) r 12
## 6 chevrolet corvette 5.7 1999 8 manual(m6) r 16
## 7 chevrolet corvette 5.7 1999 8 auto(l4) r 15
## 8 chevrolet corvette 6.2 2008 8 manual(m6) r 16
## 9 chevrolet corvette 6.2 2008 8 auto(s6) r 15
## 10 chevrolet corvette 7 2008 8 manual(m6) r 15
## hwy fl class
## <int> <chr> <chr>
## 1 20 r suv
## 2 15 e suv
## 3 20 r suv
## 4 17 r suv
## 5 17 r suv
## 6 26 p 2seater
## 7 23 p 2seater
## 8 26 p 2seater
## 9 25 p 2seater
## 10 24 p 2seater
## # … with 206 more rows
9.2.2 データの列で絞り込み
では、列方向で抽出するにはどうすれば良いのだろうか? たとえば、mpg
で言えば、manufacturer
とmodel
とtrans
とdrv
の列を抽出したいというような状況である。
このようなときは、select(抽出したい列名)
を使えば良い。抽出したい列名は、1つだけに限らず、何個書いても問題ない。
mpg %>%
select(manufacturer, model, trans, drv) # 4つの列を抽出
## # A tibble: 234 x 4
## manufacturer model trans drv
## <chr> <chr> <chr> <chr>
## 1 audi a4 auto(l5) f
## 2 audi a4 manual(m5) f
## 3 audi a4 manual(m6) f
## 4 audi a4 auto(av) f
## 5 audi a4 auto(l5) f
## 6 audi a4 manual(m5) f
## 7 audi a4 auto(av) f
## 8 audi a4 quattro manual(m5) 4
## 9 audi a4 quattro auto(l5) 4
## 10 audi a4 quattro manual(m6) 4
## # … with 224 more rows
select()
では、「A列からG列まで」というような抽出も可能である。
mpg %>%
select(manufacturer:drv) # manufacturerからdrvまでの7列を抽出
## # A tibble: 234 x 7
## manufacturer model displ year cyl trans drv
## <chr> <chr> <dbl> <int> <int> <chr> <chr>
## 1 audi a4 1.8 1999 4 auto(l5) f
## 2 audi a4 1.8 1999 4 manual(m5) f
## 3 audi a4 2 2008 4 manual(m6) f
## 4 audi a4 2 2008 4 auto(av) f
## 5 audi a4 2.8 1999 6 auto(l5) f
## 6 audi a4 2.8 1999 6 manual(m5) f
## 7 audi a4 3.1 2008 6 auto(av) f
## 8 audi a4 quattro 1.8 1999 4 manual(m5) 4
## 9 audi a4 quattro 1.8 1999 4 auto(l5) 4
## 10 audi a4 quattro 2 2008 4 manual(m6) 4
## # … with 224 more rows
select(-列名)
とすれば、指定した列を除外することもできる。
mpg %>%
select(-manufacturer) # manufacturerを除外
## # A tibble: 234 x 10
## model displ year cyl trans drv cty hwy fl class
## <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
## 1 a4 1.8 1999 4 auto(l5) f 18 29 p compact
## 2 a4 1.8 1999 4 manual(m5) f 21 29 p compact
## 3 a4 2 2008 4 manual(m6) f 20 31 p compact
## 4 a4 2 2008 4 auto(av) f 21 30 p compact
## 5 a4 2.8 1999 6 auto(l5) f 16 26 p compact
## 6 a4 2.8 1999 6 manual(m5) f 18 26 p compact
## 7 a4 3.1 2008 6 auto(av) f 18 27 p compact
## 8 a4 quattro 1.8 1999 4 manual(m5) 4 18 26 p compact
## 9 a4 quattro 1.8 1999 4 auto(l5) 4 16 25 p compact
## 10 a4 quattro 2 2008 4 manual(m6) 4 20 28 p compact
## # … with 224 more rows
9.3 追加
9.3.1 新しい列を追加
データフレームに新しい列を作るには、mutate(新しく作る列名 = 値)
を使えば良い。
mpg %>%
mutate(one = 1) # 最後尾にoneという列を追加した
## # A tibble: 234 x 12
## manufacturer model displ year cyl trans drv cty hwy
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int>
## 1 audi a4 1.8 1999 4 auto(l5) f 18 29
## 2 audi a4 1.8 1999 4 manual(m5) f 21 29
## 3 audi a4 2 2008 4 manual(m6) f 20 31
## 4 audi a4 2 2008 4 auto(av) f 21 30
## 5 audi a4 2.8 1999 6 auto(l5) f 16 26
## 6 audi a4 2.8 1999 6 manual(m5) f 18 26
## 7 audi a4 3.1 2008 6 auto(av) f 18 27
## 8 audi a4 quattro 1.8 1999 4 manual(m5) 4 18 26
## 9 audi a4 quattro 1.8 1999 4 auto(l5) 4 16 25
## 10 audi a4 quattro 2 2008 4 manual(m6) 4 20 28
## fl class one
## <chr> <chr> <dbl>
## 1 p compact 1
## 2 p compact 1
## 3 p compact 1
## 4 p compact 1
## 5 p compact 1
## 6 p compact 1
## 7 p compact 1
## 8 p compact 1
## 9 p compact 1
## 10 p compact 1
## # … with 224 more rows
上の例ではone
という列を作り、すべての行を1で埋めたが、これはあまり実践的ではない。
mutate()
が力を発揮するのは、特にif_else()
という関数と組み合わせたときである。たとえば、displ
(排気量)の値が3未満ならgood
、3以上ならbad
という列(engine
)を作りたい場合、以下のように書けば良い。
mpg %>%
mutate(engine = if_else(displ < 3, "good", "bad"))
## # A tibble: 234 x 12
## manufacturer model displ year cyl trans drv cty hwy
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int>
## 1 audi a4 1.8 1999 4 auto(l5) f 18 29
## 2 audi a4 1.8 1999 4 manual(m5) f 21 29
## 3 audi a4 2 2008 4 manual(m6) f 20 31
## 4 audi a4 2 2008 4 auto(av) f 21 30
## 5 audi a4 2.8 1999 6 auto(l5) f 16 26
## 6 audi a4 2.8 1999 6 manual(m5) f 18 26
## 7 audi a4 3.1 2008 6 auto(av) f 18 27
## 8 audi a4 quattro 1.8 1999 4 manual(m5) 4 18 26
## 9 audi a4 quattro 1.8 1999 4 auto(l5) 4 16 25
## 10 audi a4 quattro 2 2008 4 manual(m6) 4 20 28
## fl class engine
## <chr> <chr> <chr>
## 1 p compact good
## 2 p compact good
## 3 p compact good
## 4 p compact good
## 5 p compact good
## 6 p compact good
## 7 p compact bad
## 8 p compact good
## 9 p compact good
## 10 p compact good
## # … with 224 more rows
9.3.2 列名を変更
新しい列を作りたいわけではないが、列名を変えたい場合がある。このようなときは、rename(新しい列名 = 古い列名)
を使えば良い。
mpg %>%
rename(nen = year) # yearをnenに変更
## # A tibble: 234 x 11
## manufacturer model displ nen cyl trans drv cty hwy
## <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int>
## 1 audi a4 1.8 1999 4 auto(l5) f 18 29
## 2 audi a4 1.8 1999 4 manual(m5) f 21 29
## 3 audi a4 2 2008 4 manual(m6) f 20 31
## 4 audi a4 2 2008 4 auto(av) f 21 30
## 5 audi a4 2.8 1999 6 auto(l5) f 16 26
## 6 audi a4 2.8 1999 6 manual(m5) f 18 26
## 7 audi a4 3.1 2008 6 auto(av) f 18 27
## 8 audi a4 quattro 1.8 1999 4 manual(m5) 4 18 26
## 9 audi a4 quattro 1.8 1999 4 auto(l5) 4 16 25
## 10 audi a4 quattro 2 2008 4 manual(m6) 4 20 28
## fl class
## <chr> <chr>
## 1 p compact
## 2 p compact
## 3 p compact
## 4 p compact
## 5 p compact
## 6 p compact
## 7 p compact
## 8 p compact
## 9 p compact
## 10 p compact
## # … with 224 more rows
9.4 集約
統計量の算出に使えるのは、group_by()
とsummarise()
である。
まずはsummarise()
を見てみよう。書き方はsummarise(新しい列名 = 関数)
である。同時に複数の関数を使うこともできる。たとえば、displ
の平均値、標準偏差、最小値、最大値を計算したい場合、以下のように書けば良い。
mpg %>%
summarise(mean_displ = mean(displ),
sd_displ = sd(displ),
min_displ = min(displ),
max_displ = max(displ))
## # A tibble: 1 x 4
## mean_displ sd_displ min_displ max_displ
## <dbl> <dbl> <dbl> <dbl>
## 1 3.47 1.29 1.6 7
このように、summarise()
を使うと、データ全体の統計量を計算することができる。
しかし、実際の場面で全体の統計量を計算することは少なく、むしろグループごとの統計量を計算したいという場面のほうが圧倒的に多いだろう。
このようなときは、group_by(グルーピングの変数)
を使うことができる。たとえば、year
ごとにsummarise()
を実行するには、以下のように書けば良い。
mpg %>%
group_by(year) %>%
summarise(mean_displ = mean(displ),
sd_displ = sd(displ),
min_displ = min(displ),
max_displ = max(displ))
## # A tibble: 2 x 5
## year mean_displ sd_displ min_displ max_displ
## <int> <dbl> <dbl> <dbl> <dbl>
## 1 1999 3.28 1.26 1.6 6.5
## 2 2008 3.66 1.30 1.8 7
製造年(1999年と2008年)ごとに統計量を計算することができた。
9.5 結合
ここでは、mpg
ではなく、架空のデータセットを作ってみよう。たとえば、以下のような状況を考えてみてほしい。
たかし君とはなこさんは、以前見たテレビドラマに感化されて、「足袋を履いたときと、裸足のときとで、どっちが走るのが早くなるだろうか?」と疑問に思いました。そこで2人は、5日間のうち3日は足袋を履いて、2日は裸足で自宅から学校まで走り、到着までの所要時間を測りました。
2人の毎日の所要時間データはcommute
というデータフレームとして保存しよう。
commute = data.frame(
"name" = c("takashi","takashi","takashi","takashi","takashi","hanako","hanako","hanako","hanako","hanako"),
"day" = c(1,2,3,4,5,1,2,3,4,5),
"time" = c(10,13,12,11,14,9,15,14,10,16)
)
commute
## name day time
## 1 takashi 1 10
## 2 takashi 2 13
## 3 takashi 3 12
## 4 takashi 4 11
## 5 takashi 5 14
## 6 hanako 1 9
## 7 hanako 2 15
## 8 hanako 3 14
## 9 hanako 4 10
## 10 hanako 5 16
一方、足袋だったか裸足だったかは、shoes
というデータフレームとして保存しよう。
shoes = data.frame(
"day" = c(1,2,3,4,5),
"shoes" = c("tabi","tabi","bare","tabi","bare")
)
shoes
## day shoes
## 1 1 tabi
## 2 2 tabi
## 3 3 bare
## 4 4 tabi
## 5 5 bare
このようなとき、所要時間のデータと毎日の靴のデータを関係づけて可視化したいものである。しかし、別々のデータフレームとして保存されているので、今のままでは可視化できない。
このようなときは、inner_join()
という関数を使えば良い。書き方は、inner_join(結合するデータ, by = "共通の列名")
である。今回は、day
という変数が共通なので、以下のように書けば良い。
commute %>%
inner_join(shoes, by = "day")
## name day time shoes
## 1 takashi 1 10 tabi
## 2 takashi 2 13 tabi
## 3 takashi 3 12 bare
## 4 takashi 4 11 tabi
## 5 takashi 5 14 bare
## 6 hanako 1 9 tabi
## 7 hanako 2 15 tabi
## 8 hanako 3 14 bare
## 9 hanako 4 10 tabi
## 10 hanako 5 16 bare
無事2つのデータを結合することができた。
しかし、いつも共通の列名があるわけではない。たとえば、shoes
が以下のようになっていたとしよう。
shoes = data.frame(
"hinichi" = c(1,2,3,4,5), # "day"ではなく、"hinichi"という列名
"shoes" = c("tabi","tabi","bare","tabi","bare")
)
shoes
## hinichi shoes
## 1 1 tabi
## 2 2 tabi
## 3 3 bare
## 4 4 tabi
## 5 5 bare
このようなときは、以下のように書けば良い。
commute %>%
inner_join(shoes, by = c("day" = "hinichi")) # dayとhinichiを対応づけている
## name day time shoes
## 1 takashi 1 10 tabi
## 2 takashi 2 13 tabi
## 3 takashi 3 12 bare
## 4 takashi 4 11 tabi
## 5 takashi 5 14 bare
## 6 hanako 1 9 tabi
## 7 hanako 2 15 tabi
## 8 hanako 3 14 bare
## 9 hanako 4 10 tabi
## 10 hanako 5 16 bare
この他にもleft_join()
、right_join()
などの関数がある。詳しくは、https://dplyr.tidyverse.org/reference/join.html を見てほしい。
9.6 ロングフォーマット
以下の架空のデータフレーム(X, Y, Zという3つの株価の増減比の時系列データ)があったとしよう。
set.seed(1) # 乱数のシードを設定
stocks = data.frame(
time = as.Date('2009-01-01') + 0:9,
X = rnorm(10, 0, 1),
Y = rnorm(10, 0, 2),
Z = rnorm(10, 0, 4)
)
stocks
## time X Y Z
## 1 2009-01-01 -0.6264538 3.02356234 3.6759095
## 2 2009-01-02 0.1836433 0.77968647 3.1285452
## 3 2009-01-03 -0.8356286 -1.24248116 0.2982599
## 4 2009-01-04 1.5952808 -4.42939977 -7.9574068
## 5 2009-01-05 0.3295078 2.24986184 2.4793030
## 6 2009-01-06 -0.8204684 -0.08986722 -0.2245150
## 7 2009-01-07 0.4874291 -0.03238053 -0.6231820
## 8 2009-01-08 0.7383247 1.88767242 -5.8830095
## 9 2009-01-09 0.5757814 1.64244239 -1.9126002
## 10 2009-01-10 -0.3053884 1.18780264 1.6717662
このとき、3つの株価の時系列変化をプロットしてみたいが、このままではうまくいかない。なぜなら、データがロングフォーマット(列に変数名、行にデータ)という形式になっていないからである。上の表のようなデータ形式をワイドフォーマットと言う。
データをロングフォーマットに変えるには、gather()
を使えば良い。書き方は、gather(key = "新しく作るラベル", value = "新しく作る数値", ロングにしたい列(複数個))
である。文章ではわかりにくいと思うので、以下のコードを見て、何をやっているのかを理解してほしい。
stocks_long = stocks %>%
gather(key = stock, value = price, X, Y, Z) # X:Zで指定してもOK
stocks_long
## time stock price
## 1 2009-01-01 X -0.62645381
## 2 2009-01-02 X 0.18364332
## 3 2009-01-03 X -0.83562861
## 4 2009-01-04 X 1.59528080
## 5 2009-01-05 X 0.32950777
## 6 2009-01-06 X -0.82046838
## 7 2009-01-07 X 0.48742905
## 8 2009-01-08 X 0.73832471
## 9 2009-01-09 X 0.57578135
## 10 2009-01-10 X -0.30538839
## 11 2009-01-01 Y 3.02356234
## 12 2009-01-02 Y 0.77968647
## 13 2009-01-03 Y -1.24248116
## 14 2009-01-04 Y -4.42939977
## 15 2009-01-05 Y 2.24986184
## 16 2009-01-06 Y -0.08986722
## 17 2009-01-07 Y -0.03238053
## 18 2009-01-08 Y 1.88767242
## 19 2009-01-09 Y 1.64244239
## 20 2009-01-10 Y 1.18780264
## 21 2009-01-01 Z 3.67590949
## 22 2009-01-02 Z 3.12854520
## 23 2009-01-03 Z 0.29825993
## 24 2009-01-04 Z -7.95740678
## 25 2009-01-05 Z 2.47930299
## 26 2009-01-06 Z -0.22451496
## 27 2009-01-07 Z -0.62318203
## 28 2009-01-08 Z -5.88300954
## 29 2009-01-09 Z -1.91260022
## 30 2009-01-10 Z 1.67176624
ロングフォーマットにすることができた。
ロングフォーマットのデータをワイドフォーマットに戻したい場合は、spread()
を使えば良い。書き方はspread(key = ワイドにする列, value = ワイドにする値)
である。これも文章ではわかりにくいと思うので、以下のコードを見てほしい。
stocks_long %>%
spread(stock, price)
## time X Y Z
## 1 2009-01-01 -0.6264538 3.02356234 3.6759095
## 2 2009-01-02 0.1836433 0.77968647 3.1285452
## 3 2009-01-03 -0.8356286 -1.24248116 0.2982599
## 4 2009-01-04 1.5952808 -4.42939977 -7.9574068
## 5 2009-01-05 0.3295078 2.24986184 2.4793030
## 6 2009-01-06 -0.8204684 -0.08986722 -0.2245150
## 7 2009-01-07 0.4874291 -0.03238053 -0.6231820
## 8 2009-01-08 0.7383247 1.88767242 -5.8830095
## 9 2009-01-09 0.5757814 1.64244239 -1.9126002
## 10 2009-01-10 -0.3053884 1.18780264 1.6717662
ワイドフォーマットに戻すことができた。
9.7 データファイルの読み込み
実際のデータファイル(たとえばcsv、tsv、xlsxなどのスプレッドシート)は、read_csv()
やread_tsv()
、readxlパッケージのread_excel()
で読み込むことができる。
データの読み込みについては、各人の都合があると思うので、周りの人に尋ねてみてほしい30。
9.8 ggplot2との併用
パイプ演算子(%>%
)を使うと、以下のようにデータハンドリングと可視化をシームレスにつなげることができる。下の例では、平均値と標準誤差をグループごとに計算し、棒グラフとエラーバーを描いている。
mpg %>%
group_by(year) %>% # yearごとに
summarise(mean = mean(displ),
se = sd(displ) / sqrt(n())) %>% # 平均値と標準誤差を計算;n()はデータの個数を数える関数
ggplot(aes(factor(year), mean, fill = factor(year))) + # dataは「%>%」で自動的に流し込まれているので、指定しなくて良い
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = mean - se, ymax = mean + se), width = 0.2)