データを加工していきます
こんにちは、小幡です。Rを学んでおります。
前回は、Rを使えるようになるために覚えておきたい事前知識「関数」「パッケージ」「データフレーム」について勉強しました。そして第3回目となる今回は、Rのパッケージ「tidyr」を使ったデータの変形方法を勉強します。
※編集部注:初出時、本連載は全7回の予定でしたが、編集の都合上、全8回に変更しました。(2020.8.12追記)
いよいよ実際にコードを打ち込んで、データの変形を行えるようになるのが今日の目標。がんばります!
作業を始めるその前に・・・
輿石さん:前回で、パッケージを読み込むところまでできるようになりましたね。今回は実際にプログラムを書いてデータの加工をしていきますよ。
株式会社ヴァリューズ ソリューション局 マネジャー
輿石拓真(こしいし・たくま)さん
輿石さん:その前に、RStudioで分析作業を行うときに最初にすべきことをまずお伝えしますね。分析を行ったコードやインプットデータ、分析後のアウトプットデータなどを格納するフォルダを作りましょう。上部のメニューからFile→New Projectを選び、下図の通りに進めてください。今回は「Rstudy」というフォルダを作ってみましょう。途中でどこにフォルダを作るか選ぶ箇所がありますが、そこは小幡さんにお任せします。
小幡:できました!RStudioが再起動?して新しく開きました。
輿石さん:フォルダは新しく作られていますか?
小幡:作られてます。「Rstudy.Rproj」というファイルがフォルダの中に入ってますね?
輿石さん:そうですね。実は「Project」という機能を使い、今回の分析用の新しいRStudioを立ち上げたんです。分析ごとにコードやデータの保存先※1、表示されたタブなどを管理・保存してくれるのでとても便利なんです。後日分析を再開したくなったらそのProjectを開けば、タブなどの状態そのままで分析を再開できますよ。
※1正確には「作業ディレクトリ」をProjectごとに管理してくれます。7回目の記事で詳しく扱います。
小幡:Projectを開くのとRStudioを開くのは違うんですか?
輿石さん:フォルダを作成した時にできていた「Rstudy.Rproj」というファイルをクリックすると、Rstudyという名前がついた今回の分析専用のRStudioが起動するんです。「あの分析を再開しよう」となったら、作業していたフォルダにいって、「○○.Rproj」というファイルをクリックしてRStudioを起動するようにしましょう。
データの「縦持ち・横持ち」とは
輿石さん:では本題に入っていきましょう。データの「加工」です。第1回で、データには機械が読みやすい形と、人間が読みやすい形の2パターンがあるということはお話しましたよね。それは「横持ち」「縦持ち」という言葉で表現されることが多いです。
例えば、3ヶ月間のあるサイトのUU(ユニークユーザー)数をExcelで表現するとします。1つは、「横持ち」と呼ばれるもので、縦にサイトA・B・C、横に年月を入れて、交わったところに数字を入れる方法。もう1つは「縦持ち」と呼ばれる、縦にサイトA・B・Cを取って、さらに次の列に年月を取り、その組み合わせで数字が決まる方法です。
さて、小幡さんが見やすいのはどちらですか?
小幡:左ですね。左の横持ちの形式であれば、各サイトの時系列の推移や、同月内でのサイト間の比較も簡単に把握できると思います。
輿石さん:そうですよね。世にある”人間が理解しやすいデータの形”は横持ちの形式です。ただ実は、機械が理解しやすく、データの加工や集計、分析に適した形は縦持ちのデータなんです。人からデータをもらうときは横持ちになっていることが多いので、分析をするにはまず「横持ちを縦持ちのデータ形式に変更する」という作業が必要になります。
なぜ横持ちだとダメなのかを簡単に解説しておきます。例えば、横持ちの表で新たにPV(ページビュー)数も追加したいときはどうしますか?
小幡:……できないですよね? PV用の表をもう一つ作るとかですか?
輿石さん:大変そうですよね。では縦持ちの表ではどうですか?
小幡:右側につけられそうです!
輿石さん:そうです。右側に付け加えることで、UU数・PV数の2つを同じ表の中で把握できるようになります。一人当たりのPV数とかも横に付け加えられそうですよね。
輿石さん:列の追加だけでなく、サイトごとに累積PV数を出すなどの集計作業も縦持ちのデータの方が適しているんです。第4回で実感すると思いますよ。
また、両者の違いとして、縦持ちは「1つの観測対象が1行に収まる」という特徴があります。ここは結構大事なポイントです。
小幡:...。よくわかりません…(笑)。
輿石さん:難しいですよね(笑)。正確性に少し欠けるかもですが、イメージで話しますね。サイトA・202001の「100」という数字に着目してみましょう。横持ちのデータでは「100」がどんな数字かを知るためにはまず左をみてサイトAだな、次に上をみて202001だな、と、横と上のクロスで「100」という数字を説明してますよね。
対して縦持ちの方は「100」という数字をみて、1行横だけ見れば「サイトAで202001の数字だな」とわかります。この「1行だけ見ればわかるよ!」というのが「1つの観測対象が1行に収まる」ということだと思ってください。
※より正確には1行だけ見ればわかることに加えて、サイトA、202001という組み合わせの行がただ1つでなくてはなりません。
小幡:ほ~。なんとなくわかりました!1行見たらなんの数字か分かる状態が縦持ちですね! それで、なぜそれが大事なポイントなんでしょうか?
輿石さん:データ分析はまずデータを縦持ちにするところから、ですが、複雑なデータを扱おうとすると初めは何が「縦」で何が「横」なのかわからなくなってしまうことがあると思うんです。実際、僕もありました。何を目指せばいいか分からないことほど困ったことはありませんよね。そんな時に、「1つの観測対象が1行に収まる」≒「数字が何の数字か横1行見ていけばわかる」という状態を知っていると役に立つはずです。
「tidyr」パッケージによる縦持ち横持ち変換
輿石さん:それでは、今から横持ち⇔縦持ちを行き来することをやってみます。この変換をやりやすくしてくれるのが「tidyr」というパッケージです。第2回で説明したように、tidyverseパッケージを読み込むことでtidyrに含まれる関数も使えるようになりますよ。
次のコードではライブラリの読み込みと、今回加工していく学習用データの作成を行っています。新規テキストファイルを開いて、コードをコピー&ペーストして早速実行してみてください。
# 使用するパッケージの読み込み
library(tidyverse)
# 今回扱う学習用データの作成
wide_data <-tibble("site" = c("サイトA", "サイトB", "サイトC"),
"202001" = c(100, 120, 1000),
"202002" = c(120, 110, 80),
"202003" = c(1000, 1100, 2000))
# 変数だけを実行すると中身を確認できる
wide_data
●コンソールの出力内容
#> # A tibble: 3 x 4
#> site `202001` `202002` `202003`
#> <chr> <dbl> <dbl> <dbl>
#> 1 サイトA 100 120 1000
#> 2 サイトB 120 110 1100
#> 3 サイトC 1000 80 2000
輿石さん:上記のようにコンソールに出力されましたか?
小幡:はい、3サイト3か月分の横持ちのデータが表示されました!これが今回加工していくデータですね。
関数「pivot_longer」でデータを縦持ちにする
輿石さん:最初に横持ちのデータを縦持ちにする「pivot_longer」という関数の使い方を覚えていきましょう。まずは理屈抜きに、以下のコードを実行して横持ちのwide_dataを縦持ちに変換してみましょう。wide_dataといくつかの指定をインプットにpivot_longer関数を実行します。
long_data <- pivot_longer(data = wide_data, cols = -"site", names_to = "month", values_to = "uu")
long_data
●コンソールの出力内容
#> # A tibble: 9 x 3
#> site month uu
#> <chr> <chr> <dbl>
#> 1 サイトA 202001 100
#> 2 サイトA 202002 120
#> 3 サイトA 202003 1000
#> 4 サイトB 202001 120
#> 5 サイトB 202002 110
#> 6 サイトB 202003 1100
#> 7 サイトC 202001 1000
#> 8 サイトC 202002 80
#> 9 サイトC 202003 2000
小幡:3行×4列だった横持ちのデータが9行×3列の縦持ちデータになりました!関数pivot_longerで整形したデータを矢印「<-」でlong_dataという変数に代入しているんですよね。
輿石さん:そうですね。代入は第2回で学びましたね。
それでは、pivot_longerの引数(インプット)を説明します。関数ではインプットが何かを意識することが大事ですよ。まず次の表を見てみてください。
■ pivot_longer()の主な引数
引数名 | 引数の説明 |
data | 変換をしたいデータフレーム |
cols | 縦にしたい列名一覧(マイナス- での指定も可能) |
names_to | 列名を格納した列の列名 |
values_to | 値を格納した列の列名 |
輿石さん:1つ目の引数(第1引数)dataは横持ちのデータフレームを指定します。今回はwide_dataですね。残りの3つの引数の指定は次の図を見ながら学んでいきましょう。
輿石さん:2つ目の引数cols
には、縦にしたい列名の一覧を指定します。指定した列の列名と値がそれぞれ縦一列になって返ってきます。今回縦にしたい列はどれですか?
小幡:202001、202002、202003の3列ですかね。
輿石さん:そうですね。正解です。コードには-site
と記載されていますね。マイナスをつけることで、「それ以外の」という指定をすることができるんです。3列を書き並べて指定する場合はcols = c("202001", "202002", "202003")
と書きます。複数指定する場合はc()という関数で囲います。マイナスが使えると入力文字数が減って楽になるので覚えておきましょう。
小幡:分かりました!
輿石さん:次のステップは引数names_to
とvalues_to
の指定です。新しい列の名前を指定してあげましょう。
小幡:さきほどの引数説明の表には「列名を格納した列の列名」ってありますが、なんだかややこしいですね。。。
輿石さん:そうですね(笑)。横持ちのデータをもう一度見てみてください。202001、202002、202003という列名が何を表しているか分かりますか?
小幡:「年月」ですよね?横持ちのデータには年月とは書いてないですが...。
輿石さん:そうなんです。もともとの横持ちのデータには「縦にしたい列の列名が何を意味するのか」という情報がないんです。なので、202001などの列名を格納した一列を作るためにはその列名を与えてあげる必要があるんです。だから、ややこしいと言っていた「列名を格納した列の列名」というのはただの新しい列の名前を与えているだけなんですね。
小幡:そう考えると値を格納する列にも名前を付けてあげる必要がありますね。だから、names_to
とvalues_to
はただ新しい列のネーミングをしているだけ、と。難しく考えないようにします!
輿石さん:ちなみに、動かす対象列を「201901」「201902」だけにしたらどうなるでしょうか? マイナスではなくc()
を使った指定の練習もかねて次のコードを実行してみましょう。
long_data2 <- pivot_longer(data = wide_data, cols = c("202001", "202002"),
names_to = "month", values_to = "uu")
long_data2
●コンソールの出力内容#> # A tibble: 6 x 4 #> site `202003` month uu #> <chr> <dbl> <chr> <dbl> #> 1 サイトA 1000 202001 100 #> 2 サイトA 1000 202002 120 #> 3 サイトB 1100 202001 120 #> 4 サイトB 1100 202002 110 #> 5 サイトC 2000 202001 1000 #> 6 サイトC 2000 202002 80
小幡:202003
の列がそのまま残って、site
列と一緒に複製されてますね。指定しないと列が残ってしまうから、適切に指定しないといけませんね。なんとなく仕組みが分かってきました…!
輿石さん:こんな感じで少しコードを変えてみて、結果がどう変わるか見てみるのも勉強になりそうですね。
関数「pivot_wider」でデータを横持ちにする
輿石さん:今度は縦持ちから横持ちに変形する方法を学んでいきましょう。横持ちは人間が理解しやすいデータなので、主に結果を人に見せるために分析の後半で使うことが多いと思います。縦持ち横持ちはセットなので一緒にやってしまいましょう。tidyrパッケージの関数「pivot_wider」を使います。
小幡:縦にしたければlongerで、横にしたければwiderで覚えやすいですね!
輿石さん:そうですね。先ほど縦持ちにしたデータlong_data
をもう一度横持ちに戻してみましょう。次のコードを実行してみてください。
wide_data2 <- pivot_wider(data = long_data, names_from = "month", values_from = "uu") wide_data2●コンソールの出力内容
#> # A tibble: 3 x 4 #> site `202001` `202002` `202003` #> <chr> <dbl> <dbl> <dbl> #> 1 サイトA 100 120 1000 #> 2 サイトB 120 110 1100 #> 3 サイトC 1000 80 2000
小幡:できました!pivot_longerよりもpivot_widerの方が引数が少なくてシンプルですね。
輿石さん:シンプルですよね。主な引数は次の3つです。
■ pivot_wider()の主な引数
引数名 | 引数の説明 |
data | 変換をしたいデータフレーム |
names_from | 列名として展開したい列 |
values_from | 値として格納したい列 |
輿石さん:names_from
に指定した列に含まれるユニークな要素数分の列が新しくでき、その列にvalues_from
に指定した列の値が格納されていくようなイメージでデータが変形します。
小幡:質問ですが、ユニークな要素の数ってどういうことですか?
輿石さん:はい、種類の数というとわかりやすいですかね?今回names_from
にmonth
を指定していますよね。month
列は9行ですが、中の値は202001、202002、202003の3種類です。
小幡:種類の方がわかりやすいです!確かに今回はmonth
列が202001、202002、202003の3列になっていますね。縦持ちから横持ちへの変形方法もわかった気がします!
輿石さん:では、今日はここまでです。今回はtidyrパッケージのpivot_widerとpivot_longerという2つの関数を扱って、縦持ちと横持ちを行き来するやり方を勉強しました。これはデータの総量は変わっていないので、データの加工というより変形といえます。
そこで次回はdplyr(読み方:ディープライヤー)というパッケージを使い、データから新しい変数(列)を作ったり、集計したりする方法を学びましょう。dplyrを学ぶと、飛躍的に自由にデータ加工ができるようになるので、楽しみにしていてください。
小幡:分かりました。楽しみです!今日もありがとうございました!
まとめ
最後に今回学んだ内容をまとめます。今日はtidyrパッケージを使って、データを縦持ち・横持ちに変更する方法を勉強しました。
1.横持ち:人間が理解しやすいデータ。新しい変数を追加することはできなかったり、加工や集計を行うには不向き。
2.縦持ち:機械が分かりやすいデータ。新しい変数を追加することが可能。1つの観察対象が1行に収まる(数字が何の数字か横1行見ていけばわかる)。
3.pivot_longer:横持ち→縦持ちに変換する関数。縦にする列の指定と、その列の列名と値を格納する列それぞれの名前の指定を行う。
4.pivot_wider:縦持ち→横持ちに変換する関数。主に分析の最後に使うことが多い。
今日は本格的に、関数を使ってデータを扱う方法を勉強しました。よく復習して次回に臨みたいと思います。それではまた次回、お会いしましょう!
# 使用するパッケージの読み込み
library(tidyverse)
# 今回扱う学習用データの作成
wide_data <-tibble("site" = c("サイトA", "サイトB", "サイトC"),
"202001" = c(100, 120, 1000),
"202002" = c(120, 110, 80),
"202003" = c(1000, 1100, 2000))
# 変数だけを実行すると中身を確認できる
wide_data
# 横持ちから縦持ちへの変換
long_data <- pivot_longer(data = wide_data, cols = -"site",
names_to = "month", values_to = "uu")
long_data
# 横持ちから縦持ちへの変換(間違えてみるバージョン)
long_data2 <- pivot_longer(data = wide_data, cols = c("202001", "202002"),
names_to = "month", values_to = "uu")
long_data2
#縦持ちから横持ちへの変換
wide_data2 <- pivot_wider(long_data, id_cols = "site", names_from = "month", values_from = c("uu", "pv"))
wide_data2
Rでデータを加工・集計する方法とは?マーケターが1からRを勉強します【第4回】
https://manamina.valuesccg.com/articles/782マーケター1年目の小幡さんがRを学んでいきます。講師は株式会社ヴァリューズのデータアナリスト、輿石さん。第4回はパッケージ「dplyr」を使ったデータの加工・集計の方法を習得します。Rでデータを扱えるようになりたいと考えている方、ぜひ小幡さんと一緒に勉強していきましょう。
メールマガジン登録
最新調査やマーケティングに役立つ
トレンド情報をお届けします
大学でマーケティングを勉強しながら、ヴァリューズでインターンとして働いていました。2020年の春からは新卒としてヴァリューズに入社しました。