データの構造を変える時に有用なのがtidyrというパッケージです。横に広いデータを縦長のデータに変更するpivot_longerまたはgatherを使います。
tidyr本家のホームページにはgatherやspreadの関数の代わりに、
pivot_longer()をpivot_wider()を使うことが推奨されています。
Development on
https://tidyr.tidyverse.org/reference/gather.htmlgather()
is complete, and for new code we recommend switching topivot_longer()
, which is easier to use, more featureful, and still under active development.
pivotal_longerだけ覚えたいという方は途中のgatherを読み飛ばしてください。
便利なtidyverseに入っていますので、これを利用していきましょう。ではRStudioを開いて準備をしていきます。
データセットの準備
まずは作業ディレクトリをセットして、tidyverseを起動しています。
setwd("~/Rpractice/")
library(tidyverse)
次にアヤメのサンプルデータを使っていきましょう。head()でデータのはじめのほうを表示します。
a <- iris
> head(a)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
summary()も便利です。
> summary(a)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50
Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50
Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
>
Minは最小値、1st Quは第一四分位数、Medianは中央値、Meanは平均値、3rd Quは第三四分位数、Maxは最大値です。QuはQuartileですね。
Speciesにsetosa、versicolor、virginicaがあり、それぞれ50ずつのデータが入っていることもわかります。データすべてを確認するには、View()を使ってみてください。
View(a)
データのはじめにIDを入れる
これから並び替えをしますので、IDを入れておくと混乱は避けることができます。またspreadを使うときにもIDとなるものが必要です。
tidyverseの中のdplyrを使ってみます。その中にmutate
というファンクションがあります。
a2 <- a %>%
dplyr::mutate(a, ID=rownames(a))
またはtibbleというパッケージのrownames_to_column
でもいけます
tibble
もtidyverseの中の一つです。
a2 <- a %>%
tibble::rownames_to_column(var = "ID")
初心者の間はこういうものがあるんだ、くらいの感覚でいいと思います。またわからなくなったらここに戻ってきて参照してください。
%>%はパイプまたはパイプ演算子と呼びます。一つ前の出力を次のプログラムに代入します。
パイプを使うことでデータを指定すべきことを省略できます。一つ前の出力をそのまま代入できる便利モノです。下の2つは同じ意味です。
a2 <- a %>%
tibble::rownames_to_column(var = "ID")
a2 <- tibble::rownames_to_column(a, var = "ID")
RStudioではShift + Ctrl + Mを押すと%>%が出てきます。出力を縦に流れるようにつないで行くことができます。
x <- a %>%
group_by(Species) %>%
dplyr::summarise_each(funs(mean, sd), Sepal.Length, Sepal.Width)
> x
# A tibble: 3 x 5
Species Sepal.Length_mean Sepal.Width_mean Sepal.Length_sd Sepal.Width_sd
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 3.43 0.352 0.379
2 versicolor 5.94 2.77 0.516 0.314
3 virginica 6.59 2.97 0.636 0.322
>
gatherで縦のデータにする
tidyrパッケージのgatherを使っていきましょう
df %>% gather("key", "value", x, y, z)
で使います。それではアヤメデータで使っていきましょう。
b <- a2 %>%
tidyr::gather(key = FlowerAtt,
value = Values,
Sepal.Length:Petal.Width)
> head(b)
ID Species FlowerAtt Values
1 1 setosa Sepal.Length 5.1
2 2 setosa Sepal.Length 4.9
3 3 setosa Sepal.Length 4.7
4 4 setosa Sepal.Length 4.6
5 5 setosa Sepal.Length 5.0
6 6 setosa Sepal.Length 5.4
>
このkey、valueがはじめのうちはよくわからないと思います。
後ろ(下)から説明をします。
3番目の入力Sepal.Length:Petal.Widthは縦に並べたい変数名です。
2番目のvalueは変数名で、数値の入った列に名前をつけます。
最初のkeyは横並びしていた変数名が縦に並んだ、その列について名前をつけます。
FlowerAttのAttはAttributeですが、keyは自分の付けたい名前をつけることができます。
コロンの使い方は、例えばABCDEと並んでいたときに、A:Eと書くというもので、下の書き方と同じです。
Sepal.Length:Petal.WidthはSepal.Length、Sepal.Width、Petal.Length、Petal.Widthになります。
b <- a2 %>%
tidyr::gather(key = FlowerAtt,
Value = Values,
Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)
次になにかを残したいときは、項目名の前に-をつけます。例えばSepal.WidthとPetal.Lengthを残したいときには次のようにかきます。
c <- a2 %>%
tidyr::gather(key = FlowerAtt,
value = Values,
Sepal.Length:Petal.Width,
-Sepal.Width, -Petal.Length)
> head(c)
ID Sepal.Width Petal.Length Species FlowerAtt Values
1 1 3.5 1.4 setosa Sepal.Length 5.1
2 2 3.0 1.4 setosa Sepal.Length 4.9
3 3 3.2 1.3 setosa Sepal.Length 4.7
4 4 3.1 1.5 setosa Sepal.Length 4.6
5 5 3.6 1.4 setosa Sepal.Length 5.0
6 6 3.9 1.7 setosa Sepal.Length 5.4
>
除外したSepal.WidthとPetal.Lengthが残っているのがわかります。
Pivotal_longerで縦長のデータに変形をする
gatherは直感的にわかりにくく、また引数も覚えにくいので、開発者自身も毎回ドキュメンテーションを見ないといけない、という趣旨のことが書いてあります(笑)。
それをより使いやすくしたのが、pivot_longer
です。こちらだけ覚えていいと思います。
pivot_longer(data, cols, names_to = "name", values_to = "value")
cols
は縦長に変形をする列を記載します(アヤメのデータではSepal.Length、Sepal.Widthなどです)。
names_to
では、縦長にした列名の列に新しい名前をつけます(上の例ではFlowerAttとつけていました)。
values_to
は縦長になった変数の列に名前をつけます(Valuesとつけていました)。
ではやってみましょう。
A <- a2 %>%
pivot_longer(cols = Sepal.Length:Petal.Width,
names_to = "FlowerAtt",
values_to = "Values")
> head(A)
# A tibble: 6 x 4
ID Species FlowerAtt Values
<chr> <fct> <chr> <dbl>
1 1 setosa Sepal.Length 5.1
2 1 setosa Sepal.Width 3.5
3 1 setosa Petal.Length 1.4
4 1 setosa Petal.Width 0.2
5 2 setosa Sepal.Length 4.9
6 2 setosa Sepal.Width 3
>
cols
の複数指定の方法はいくつかあるようですが、 個別に指定する方法を示します。cols = c()
で項目名を個別に指定をすることができます。
A <- a2 %>%
pivot_longer(cols = c(Sepal.Length, Sepal.Width,
Petal.Length, Petal.Width),
names_to = "FlowerAtt",
values_to = "Values")
変形する列をcols
で指定しましたが、変形しない列を-で指定することもできます。
B <- a2 %>%
pivot_longer(cols = -c(ID, Species),
names_to = "Measurement",
values_to = "Values")
> head(B)
# A tibble: 6 x 4
ID Species Measurement Values
<chr> <fct> <chr> <dbl>
1 1 setosa Sepal.Length 5.1
2 1 setosa Sepal.Width 3.5
3 1 setosa Petal.Length 1.4
4 1 setosa Petal.Width 0.2
5 2 setosa Sepal.Length 4.9
6 2 setosa Sepal.Width 3
>
今回細かいオプションは説明をしていませんが、これらができれば十分に便利だと思います。また別の記事でspreadとpivot_widerを紹介します。
お役に立ちましたら幸いです。