Rでデータを加工・集計する3つの操作を解説。 マーケターが1からRを勉強します【第5回】

Rでデータを加工・集計する3つの操作を解説。 マーケターが1からRを勉強します【第5回】

マーケター1年目の小幡さんがRを学んでいきます。講師は株式会社ヴァリューズのデータアナリスト、輿石さん。第5回はRを使ったデータの要約、列の追加、データのグループ化の3操作を習得します。Rでデータを扱えるようになりたいと考えている方、ぜひ小幡さんと一緒に勉強していきましょう。


前回までの進捗

こんにちは、小幡です。Rを学んでおります。

前回は「dplyr」というパッケージを使ってデータ集計の7つの処理のうち、selectarrangefilterの3つを勉強しました。列を絞る、特定の順番で並び替える、行の一部を取り出す、といった操作ができるようになりました。一つ一つは今までExcelでやっていたような単純な操作ですが、組み合わせてコードを書くことで少し高度なこともできるようになった気がします。

そして今回は、前回と同じ「dplyr」のパッケージの残りの基本的な関数について勉強します。

※編集部注:記事分割の関係上、シリーズを全7回から全8回に変更しました。

もう全体の中では折返し地点を超えています。だんだんとゴールが見えてきました…! では早速、輿石さんよろしくお願いします!

データの要約、列の追加、グループ化の3操作

輿石さん:さて、今回はデータフレームに対する7つの操作のうち、残りの4つをお伝えしていきます。集計処理を行うsummariseや、処理をグループ化するgroup_byなどの基本操作を覚えたら、Rはさらに強力なツールとなっているはずですよ。

株式会社ヴァリューズ ソリューション局 マネジャー
輿石拓真(こしいし・たくま)さん

輿石さん:前回と同じように健康系のサプリメントECを想定したサンプルのデータを使っていきます。次のコードを打ち込んで、データフレームを用意しましょう。

●コード
# packageの読み込み
library(tidyverse)

# データの読み込み
kenko_ec_data <- read_tsv("https://adcreative.valuesccg.net/manamina/article/manaminar/kenko_ec_sample.tsv")
kenko_ec_data
●コンソールの出力内容
#> # A tibble: 10,361 x 7
#>    userid purchase_date item_category series price purchase_amount
#>    <chr>  <date>        <chr>         <chr>  <dbl>           <int>
#>  1 K00002 2020-01-07    マルチ酵素    お徳用  3186               1
#>  2 K00003 2020-03-24    カルシウム    プレミアム~   934               1
#>  3 K00005 2020-01-30    クレアチン    スタンダー~  2560               1
#>  4 K00008 2020-01-30    乳酸菌        プレミアム~  2574               1
#>  5 K00009 2020-01-15    クエン酸      スタンダー~  1080               1
#>  6 K00010 2020-03-22    ビタミンB     お徳用  1617               1
#>  7 K00019 2020-03-21    グルコサミン  お徳用  5329               3
#>  8 K00023 2020-01-05    ビタミンB     プレミアム~   778               1
#>  9 K00027 2020-03-13    スピルリナ    お徳用  5713               5
#> 10 K00031 2020-02-12    BCAA          スタンダー~  3694               1
#> # ... with 10,351 more rows, and 1 more variable: item_name <chr>

4.データを要約する

輿石さん:では早速、データを要約・集計する関数「summarise」について学びましょう。使い方はsummarise(データフレーム, 新列名1 = 式1, 新列名 = 式2, …)の形です。

summariseはデータフレームを集計し、集計値に要約する働きをします。次の図は、1つのデータフレームからUU(人数)とPV数合計を集計するイメージ図です。summariseに記載した列名と集計値だけの1行のデータフレームが出力されます。

輿石さん:例えばkenko_ec_dataから「ユーザーIDの種類の数=UU数」と「売れた個数の総計」を知りたいという場合は次のようにします。kenko_ec_dataをuserid、purchase_amountで集計してみましょう。

●コード
summarise(kenko_ec_data, uu = n_distinct(userid), purchase_amount_sum = sum(purchase_amount))
●コンソールの出力内容
# A tibble: 1 x 2
     uu purchase_amount_sum
  <int>               <dbl>
1  3000               17398

輿石さん:データフレームkenko_ec_dataに対して、合計する関数sum()purchase_amountを足し上げています。また、関数n_distinct()は重複のない値の個数を数える関数で、この場合にはuseridの数なのでユニークユーザー数になりますね。それぞれを新しい列purchase_amount_sumuuとして出力しています。このデータフレームには3000人分のデータが含まれていて、合計で17398点の商品が購入されているのがわかりましたね。

輿石さん:ここではsum()n_distinct()という関数を使っていますが、このような、集計に使う関数のバリエーションを増やすとできることが広がります。例えば関数max()で列の中で一番多い数値を出したり、関数mean()で平均値を出したり。

小幡:なるほど、まだまだいろいろ関数があるんですね…!

輿石さん:そうですね。集計によく使う関数をまとめておきます。これらはデータフレームの列をインプットに1つの集計値を出力するという特徴があり、僕は集計関数と呼んでます。

関数関数の概要
sum()合計値
mean()平均値
max()/min()最大値/最小値
n_distinct()ユニークな要素の数(要素の種類の数)
n()行数 ※引数は何も取らないので注意


5.新しい列を追加する

輿石さん:今度は「mutate」です。もともとの列に処理をして、新しい列を追加する関数ですね。使い方はmutate(データフレーム, 新列名1 = 式1, 新列名2 = 式2, …)という形。先ほどのsummariseと引数は似ていますが、要約するのではなく、列を追加する働きをします。

横に新しく列が追加される

輿石さん:ユニークユーザー数をuu、支払い金額(価格に購入数をかけたもの)をpaymentという列として追加してみましょう。

●コード
kenko_ec_data_m <- mutate(kenko_ec_data, uu = n_distinct(userid), payment = price * purchase_amount)

# 追加した列が確認しようにselectで列を絞って表示
select(kenko_ec_data_m, userid, price, purchase_amount, uu, payment)

●コンソールの出力内容
# A tibble: 10,361 x 5
   userid price purchase_amount    uu payment
   <chr>  <dbl>           <dbl> <int>   <dbl>
 1 K00002  3186               1  3000    3186
 2 K00003   934               1  3000     934
 3 K00005  2560               1  3000    2560
 4 K00008  2574               1  3000    2574
 5 K00009  1080               1  3000    1080
 6 K00010  1617               1  3000    1617
 7 K00019  5329               3  3000   15987
 8 K00023   778               1  3000     778
 9 K00027  5713               5  3000   28565
10 K00031  3694               1  3000    3694
# ... with 10,351 more rows


小幡uuにはすべて同じ値が入っていますね?

輿石さんmutateの中でuuのように1つの値を返す計算が行われると、すべての行に同じ1つの値が格納されます。summariseで勉強した集計関数を使うケースですね。集計以外の計算を行うとそれぞれの行ごとに計算が行われます。単純に2倍するとか、列同士を足し算する、割り算するなどが当てはまります。

小幡:なるほど、分かりました!

6.グループ化された集計を行う

輿石さん:本日最後の操作はgroup_byです。これはsummariseをはじめとする今まで勉強してきたデータフレームに変更を加える関数と一緒に使うことで真価を発揮します。group_by(データフレーム, 列1, 列2, ...)というように列名を指定します。試しにgroup_byを実行してみましょう。

●コード
group_by(kenko_ec_data, item_category, series)
●コンソールの出力内容
# A tibble: 10,361 x 7
# Groups:   item_category, series [154]
   userid purchase_date item_category series       price purchase_amount item_name                                  
   <chr>  <date>        <chr>         <chr>        <dbl>           <dbl> <chr>                                      
 1 K00002 2020-01-07    マルチ酵素    お徳用        3186               1 マルチ酵素 サプリメント お徳用 90日分      
 2 K00003 2020-03-24    カルシウム    プレミアム     934               1 カルシウム サプリメント プレミアム 30日分  
 3 K00005 2020-01-30    クレアチン    スタンダード  2560               1 クレアチン サプリメント スタンダード 30日分
 4 K00008 2020-01-30    乳酸菌        プレミアム    2574               1 乳酸菌 サプリメント プレミアム 30日分      
 5 K00009 2020-01-15    クエン酸      スタンダード  1080               1 クエン酸 サプリメント スタンダード 30日分  
 6 K00010 2020-03-22    ビタミンB     お徳用        1617               1 ビタミンB サプリメント お徳用 90日分       
 7 K00019 2020-03-21    グルコサミン  お徳用        5329               3 グルコサミン サプリメント お徳用 90日分    
 8 K00023 2020-01-05    ビタミンB     プレミアム     778               1 ビタミンB サプリメント プレミアム 30日分   
 9 K00027 2020-03-13    スピルリナ    お徳用        5713               5 スピルリナ サプリメント お徳用 90日分      
10 K00031 2020-02-12    BCAA          スタンダード  3694               1 BCAA サプリメント スタンダード 30日分      
# ... with 10,351 more rows

小幡:あれ、一見もとのkenko_ec_dataから何も変わっていないように見えますが…。

輿石さん:そうですね。ただ、出力結果の2行目に「# Groups: item_category, series [154]」と記載されているのが分かりますか? これはデータフレームがitem_categoryseriesの組み合わせで154個にグループ化されていることを表しています。見た目は変わりませんが、実はデータフレームが154個に分割されているんです。

小幡:実は分割されている...?

輿石さん:グループ化したデータフレームをsummariseで集計してみましょう。

●コード
kenko_ec_data_g <- group_by(kenko_ec_data, item_category)
summarise(kenko_ec_data_g, uu = n_distinct(userid))

●コンソールの出力内容
# A tibble: 54 x 2
   item_category         uu
   <chr>              <int>
 1 BCAA                 322
 2 DHA                  236
 3 EPA                   40
 4 L-グルタミン         138
 5 L-シトルリン         215
 6 L-リジン              57
 7 アミノ酸             236
 8 ウコン               160
 9 オルニチン           141
10 カゼインプロテイン    64
# ... with 44 more rows

小幡group_byに指定したカテゴリごとにuu数が集計されてますね!

輿石さんgroup_byをした後は、group_byに指定した列に含まれる種類ごとに処理が行われるんです。下図を見てください。group_byをすると、データフレームが指定した列の種類別に分割されて、それぞれにsummariseが適用されて、最後は1つにくっついて出力される、というイメージを持ってください。

小幡group_byと書くだけで、実は裏で分割が行われていて、何回も集計を繰り返してくれているんですね。

輿石さんsummariseだけではなくmutatefilterも、同じようにグループ化したデータフレームに使うとグループごとに適応されます。最後に1点注意ですが、summariseを行うとグループの情報が1列なくなります。実際にコードを実行して確かめてみましょう。

●コード
kenko_ec_data_g2 <- group_by(kenko_ec_data, item_category, series)
summarise(kenko_ec_data_g2, uu = n_distinct(userid))
●コンソールの出力内容
# A tibble: 154 x 3
# Groups:   item_category [54]
   item_category series          uu
   <chr>         <chr>        <int>
 1 BCAA          お徳用          87
 2 BCAA          スタンダード   173
 3 BCAA          プレミアム     103
 4 DHA           お徳用          54
 5 DHA           スタンダード   112
 6 DHA           プレミアム      84
 7 EPA           お徳用           5
 8 EPA           スタンダード    20
 9 EPA           プレミアム      16
10 L-グルタミン  お徳用          54
# ... with 144 more rows

輿石さんitem_category seriesの組み合わせでグループ化しましたが、summariseの出力結果はitem_categoryだけになっています。「# Groups: item_category [54]」という記載から分かりますね。慣れるまでは「今どの列でグループ化されているんだろう?」と確認しながら進めると良いと思います。グループ化を解除したいときはungroup(グループ化されたデータフレーム)と実行します。覚えておきましょう。

輿石さん: 最後に練習問題を1題解いてみましょう。

小幡:はいっ!

輿石さんkenko_ec_dataから、単価(price)が1000以上の商品(item_categoryseriesの組み合わせを商品とします)の中で、売上が大きいランキングを作成してください。ついでに商品の購入者数もわかるようなランキングにしましょう。

小幡:少し難しそうですがチャレンジしてみます!

輿石さん:今まで勉強した関数を使って少しずつデータフレームを加工していけばたどり着けます。単純な処理を組み合わせることを意識してやってみましょう!

考える小幡さん

小幡:はい、出来ました!

●コード
# 練習問題
# まず、1000円以上の商品に絞ったデータフレームにする
kenko_ec_data_tmp1 <- filter(kenko_ec_data, price >= 1000)

# 売上を計算したいので、単価×購入数で売上を表す列を追加する。
kenko_ec_data_tmp2 <- mutate(kenko_ec_data_tmp1, payment = price * purchase_amount)

# 「商品ごと」なので、item_category,とseriesの2列でグループ化する。
kenko_ec_data_tmp3 <- group_by(kenko_ec_data_tmp2, item_category, series)

# summariseで集計。
kenko_ec_data_tmp4 <- summarise(kenko_ec_data_tmp3, payment_sum = sum(payment), uu = n_distinct(userid))

# ランキングなのでarrangeで降順に並び替える。
output <- arrange(kenko_ec_data_tmp4, desc(payment_sum))
output
●コンソールの出力内容
# A tibble: 140 x 4
# Groups:   item_category [53]
   item_category           series       payment_sum    uu
   <chr>                   <chr>              <dbl> <int>
 1 ホエイプロテイン        お徳用           6846400   395
 2 ホエイプロテイン        プレミアム       3530228   391
 3 ホエイプロテイン        スタンダード     2571828   358
 4 BCAA                    お徳用           1904843    87
 5 マルチビタミン&ミネラル お徳用           1894352   219
 6 乳酸菌                  お徳用           1400652   136
 7 BCAA                    スタンダード     1381556   173
 8 BCAA                    プレミアム        801934   103
 9 コラーゲン              お徳用            788400    88
10 ビフィズス菌            お徳用            742720   104
# ... with 130 more rows

小幡:単価1000円以上の商品の中で一番売り上げが大きいのはホエイプロテインのお徳用で、395人が購入していますね。

輿石さん:正解です!dplyrにも慣れてきましたね!今回はここまでです。次回はデータフレームを結合する「JOIN」と、連続した処理の記述に便利な「パイプ演算子」を勉強しましょう。

まとめ

今回でdplyrパッケージの7つの基本操作のうち、6つを学び終えました。dplyrの学習にも終わりが見えてきて、少し難しい集計もできるようになってきた気がします!

●本日のコードまとめ
# packageの読み込み
library(tidyverse)

# データの読み込み
kenko_ec_data <- read_tsv("https://adcreative.valuesccg.net/manamina/article/manaminar/kenko_ec_sample.tsv")
kenko_ec_data

# summariseでデータを集計する
summarise(kenko_ec_data, uu = n_distinct(userid), purchase_amount_sum = sum(purchase_amount))

# mutateで列を追加する
kenko_ec_data_m <- mutate(kenko_ec_data, uu = n_distinct(userid), payment = price * purchase_amount)

## 列追加が見やすいようにselectで列を絞る
select(kenko_ec_data_m, userid, price, purchase_amount, uu, payment)

# group_byでグループ化した処理を行う
group_by(kenko_ec_data, item_category, series)

## group_byの後にsummariseで集計する
kenko_ec_data_g <- group_by(kenko_ec_data, item_category)
summarise(kenko_ec_data_g, uu = n_distinct(userid))

## summariseを行うとグループ化した列が1つなくなる
kenko_ec_data_g <- group_by(kenko_ec_data, item_category, series)
summarise(kenko_ec_data_g, uu = n_distinct(userid))

# 練習問題
## まず、1000円以上の商品に絞ったデータフレームにする
kenko_ec_data_tmp1 <- filter(kenko_ec_data, price >= 1000)

## 売上を計算したいので、単価×購入数で売上を表す列を追加する。
kenko_ec_data_tmp2 <- mutate(kenko_ec_data_tmp1, payment = price * purchase_amount)

## 「商品ごと」なので、item_category,とseriesの2列でグループ化する。
kenko_ec_data_tmp3 <- group_by(kenko_ec_data_tmp2, item_category, series)

## summariseで集計。
kenko_ec_data_tmp4 <- summarise(kenko_ec_data_tmp3, payment_sum = sum(payment), uu = n_distinct(userid))

## ランキングなのでarrangeで降順に並び替える。
output <- arrange(kenko_ec_data_tmp4, desc(payment_sum))
output
次回の記事はこちら

Rで複数のデータフレームを結合するJOIN関数の使い方とは。マーケターが1からRを勉強します【第6回】

https://manamina.valuesccg.com/articles/898

マーケター1年目の小幡さんがRを学んでいきます。講師は株式会社ヴァリューズのデータアナリスト、輿石さん。第6回はRを使ったデータ同士を結合させるjoin関数を習得します。Rでデータを扱えるようになりたいと考えている方、ぜひ小幡さんと一緒に勉強していきましょう。

​​

メールマガジン登録

最新調査やマーケティングに役立つ
トレンド情報をお届けします

この記事のライター

大学でマーケティングを勉強しながら、ヴァリューズでインターンとして働いていました。2020年の春からは新卒としてヴァリューズに入社しました。

関連する投稿


「社内ハッカソン」の事前準備と進め方実例を公開!成功のポイントとは?

「社内ハッカソン」の事前準備と進め方実例を公開!成功のポイントとは?

エンジニアが参加・実施しているイメージがある「ハッカソン」。普段の業務ルーティーンの中では生まれづらい交流やスキル取得が模索できるメリットを持ち合わせています。一方で具体的にどのようなことが必要なのか、知らない方も多いかもしれません。そこで今回、ヴァリューズ在籍の4名の社員がハッカソンの準備から実装までを行いました。実際に体験・紹介することで、新たな気づきが得られるかもしれません。


お金の悩み相談の先に専門家がいる。「マネコミ!」がオウンドメディアで目指すこと

お金の悩み相談の先に専門家がいる。「マネコミ!」がオウンドメディアで目指すこと

保険会社のオウンドメディアとしてSEOでの集客数が多い「マネコミ!」。ローンチから3年目(2022年度)の最大月間UU数は60万に達しています。そんな「マネコミ!」を展開する東京海上日動あんしん生命保険株式会社は、なぜオウンドメディアを立ち上げたのか、どのように運営されているのか、そしてオウンドメディアが同社の成長にどう影響しているのかについて、デジタル戦略部企画グループの齋藤 瞬(さいとう わたる)さんに伺いました。


サブスクや課金サービス運営はなぜ難しい?「無料」「有料」サービスの境界線を探る「有料会員向けのユーザーアンケート」の価値とは

サブスクや課金サービス運営はなぜ難しい?「無料」「有料」サービスの境界線を探る「有料会員向けのユーザーアンケート」の価値とは

サービスを無料で楽しんだり、売買ができたりするだけでなく、さらなる付加価値を手に入れられる「有料サービス」。昨今はユーザーが月1回、年1回など料金を支払って受けられるサブスクリプションなどのサービスも様々でてきています。マネタイズの観点でも、価格×会員数で収益が見込めるため、運営がしやすいようにも見られがちです。しかし実際には「制作費・人件費を含めると赤字」「廃止の判断が難しく、運営が続いている」という悩みの声が上がっているというのです。今回は有料モデルについて、リサーチャーの菅原大介さんに解説いただきました。


マーケターの仕事は、分かりやすい言葉で「伝える」こと。BtoBビジネスにおけるターゲットの理解とDockpit活用法

マーケターの仕事は、分かりやすい言葉で「伝える」こと。BtoBビジネスにおけるターゲットの理解とDockpit活用法

サイバーセキュリティ製品というと、難しいイメージがありませんか?ふるまい防御やサンドボックス機能など耳にしたことがない機能があり、海外の製品情報に翻訳をかけただけでは難解な領域において、「伝える」ことを追求しているのがソフトバンクグループ企業のSB C&S株式会社のシマンテック事業のチームです。伝わる商品訴求のためには、ターゲットの理解やペルソナの設定が必要不可欠。今回は、同社がどのようにWeb行動ログ分析ツール「Dockpit」を活用し、マーケティング施策につなげているのか、ICT事業本部でプロダクトマーケティングを担当している須賀田淳氏に伺いました。


お菓子業界5社をマーケティング視点で企業研究! 大学生のデータドリブン就活|2022年最新版

お菓子業界5社をマーケティング視点で企業研究! 大学生のデータドリブン就活|2022年最新版

お菓子業界大手の「森永製菓」「江崎グリコ」「カルビー」「ブルボン」「不二家」。各公式サイトの集客状況に注目し、強みや施策の違いを調査します。2年半前に公開した同記事の最新版として、新たな発見をお届けします。


最新の投稿


GWに10連休を取得する人は約2割!連休の予定はインバウンドの影響か「国内旅行」が下降し「家事」が上昇【mitoriz調査】

GWに10連休を取得する人は約2割!連休の予定はインバウンドの影響か「国内旅行」が下降し「家事」が上昇【mitoriz調査】

株式会社mitorizは、消費者購買行動データサービス「Point of Buy®」の会員に対し「大型連休に関する調査」を実施し、結果を公開しました。


Supportive fans are willing to spend money? “Oshikatsu” insights & applying it to marketing strategy

Supportive fans are willing to spend money? “Oshikatsu” insights & applying it to marketing strategy

“Oshikatsu” stimulates consumption in Japan. In fact, more than 80-90% of teens answered that they have an “Oshi.” We will deepen our understanding by investigating the current state of the “Oshikatsu” market, behaviors like time and money spent on “Oshikatsu,” and its connection with collaborations, etc. in marketing.


三井不動産、ECブランドの成長を支援するプラットフォームを提供開始

三井不動産、ECブランドの成長を支援するプラットフォームを提供開始

三井不動産株式会社は、統合コマースプラットフォーム「ecforce」を提供する株式会社SUPER STUDIOとともに、ECブランドの成長を“商業”と“物流”の両面から支援するプラットフォームを提供開始したことを発表しました。


【TVドラマランキング】共感性や独自性が話題に。「不適切にもほどがある!」「君が心をくれたから」など

【TVドラマランキング】共感性や独自性が話題に。「不適切にもほどがある!」「君が心をくれたから」など

近年動画配信サービスが普及し、時間や場所にとらわれず様々なジャンルの動画を手軽に視聴できるようになりました。テレビ離れが幅広い年代で囁かれている時代、話題になるテレビドラマとは、どのようなものなのでしょうか。今回は、2024年1月~3月に放送されたドラマについて、認知度や視聴方法、満足度、満足理由などをランキング化。その実態を探りました。


配膳ロボットの認知率は約9割、現在利用率は6割 1年後には利用率1.4倍伸びる!?【LINEリサーチ調査】

配膳ロボットの認知率は約9割、現在利用率は6割 1年後には利用率1.4倍伸びる!?【LINEリサーチ調査】

LINEリサーチは、今と近未来の流行予想を目的として「配膳ロボット」にかんする流行予想調査を実施し、その結果を公開しました。


競合も、業界も、トレンドもわかる、マーケターのためのリサーチエンジン Dockpit 無料登録はこちら

ページトップへ