Shiny100本ノック、4回目の公開となります。
さて、No.1 ~ No.2ではGoogleアナリティクスのデータをAPI経由で取得して、グラフ可視化するところまでやりました。
www.randpy.tokyo
www.randpy.tokyo
No.3では、グラフの見た目をインタラクティブに変更して、その結果をパワーポイントとして出力する練習をしました。
www.randpy.tokyo
そこで今回は、今まで勉強したところ組み合わせて
・Google アナリティクスAPIからデータ取得
・取得したデータをもとにグラフで可視化
・グラフの見た目をある程度柔軟に変更(ここまででGoogle Data Studio的な機能は再現?)
・生成したグラフをパワーポイントにしてダウンロード(Google Data Studioを超えた?)
というツールを作ってみます!!
いやこれもう、気の利いたデザイナー雇ってUIをかっこよくしたら、サービスとして売れちゃんじゃないか?
っていうレベルまで来たかもしれません。
今回作成するShinyアプリのイメージ
No.1とNo.2でも登場した、navbarPageとtabPanelを使って2つのタブを持つアプリを作ります。1つ目のタブは、Google認証を行うページ。2つ目は実際にmetricやdimensionを指定してデータを取得して、グラフ化とパワーポイントダウンロードを行うページです。
1ページ目のイメージ
まず、Googleアカウントに連携して、そこから対象のGoogle アナリティクスアカウントを選択します。
2ページ目のイメージ
データ取得機能
まず、Google アナリティクスからmetricやdimension、期間を指定してデータを表形式で出力します。このmetricやdimensionに関する知識が無い方は、Googleスプレッドシートの公式Googleアナリティクスプラグインこちらの記事を参考にしてみてください。
グラフ生成機能
次に、グラフの形式と色のイメージを選択してグラフを生成します。なお、選択できるグラフの種類は以下の6種類です。
- 円グラフ
- 棒グラフ(タイプ1、タイプ2)
- 散布図
- 折れ線グラフ
- 面グラフ
グラフ形式選択後、暖色系か寒色系かなどなど色を選択して、「グラフを出力」ボタンを押しましょう。
すると、お望みのグラフが生成されます。色を変えたりしながら様々なグラフを試してみましょう。
パワーポイントダウンロード機能
次に、「このグラフはパワーポイントで出力したい」というものがあれば、「ユーザー数」などグラフのタイトルを入力し、「グラフをスライドに追加」ボタンを押しましょう。このスライド追加ボタンは何度でも押すことができます。気に入ったグラフがあれば、保存するイメージでボタンを押しましょう。
さて、最後に、これまで上の操作で保存したグラフたちをパワーポイントで生成します。
「Download」ボタンを押すと、追加したグラフが多い場合処理に時間はかかりますが、そのうちダウンロードが開始されます。
パワーポイントイメージ
はい、こんな感じで追加した分だけパワーポイントで生成してくれます。
例えばクライアントからアクセス解析を依頼された場合は、このツールでカッコイイグラフを作りパワーポイント生成し、その後コメントを追記すれば立派なアクセス解析資料となります。
これで〇〇万円とか受注できるのは大変ありがたいのではないでしょうか?
コード解説…の前の事前準備
いつも通り、コードはGithubにアップしてあります。github.com
こちらのディレクトリを手元にダウンロードしてもらえれば、動くはずです。
なお、GoogleアナリティクスAPIを使うにあたって、
- クライアントID
- クライアントシークレット
が必要なので、まだ取得していない方はGoogle Developer Consoleを参考に取得しておいてください。
取得できたらserver.Rファイル内の、14行目と15行目に入力しておいてください。
そして扱うライブラリですが、結構多いです。それぞれまだインストールしていない方はインストールしておきましょう。
install.packages("shiny", dependencies = TRUE) install.packages("ggplot2", dependencies = TRUE) install.packages("testthat", dependencies = TRUE) install.packages("googleAnalyticsR", dependencies = TRUE) install.packages("googleAuthR", dependencies = TRUE) install.packages("listviewer", dependencies = TRUE) install.packages("gridExtra", dependencies = TRUE) install.packages("Rmisc", dependencies = TRUE) install.packages("dplyr", dependencies = TRUE) install.packages("ReporteRs", dependencies = TRUE) install.packages("rJava", dependencies = TRUE) install.packages("RColorBrewer", dependencies = TRUE)
なお、ReporteRsとrJavaはパワーポイントを生成するためのライブラリです。ちょっとインストールに引っかかる際は、
www.randpy.tokyo
を参考にしましょう。
コード解説
Googleアナリティクスからデータを取得する部分はNo.1にて、取得したデータをグラフ化する部分はNo.2にて、グラフの色を変更しパワーポイントダウンロードする部分はNo.3にてそれぞれ解説しているので、新しく学習することはあまりありません。自分自身も、かなり楽勝だろうと思っていたのですが、生成したグラフをパワーポイントに追加する部分で3時間くらい躓きました…。
reactiveValues
今回作りたかった機能として、グラフを作成後に「これはパワーポイントに追加したいな」と思ったら「追加ボタン」を押す、という操作を何度か繰り返すことを想定していました。その際に、これまで通りactionButtonをトリガーが押されるたびに、eventReactiveを使ってどうにかグラフを追加しようとすると、過去に追加されたデータに上書きがなされてしまってデータを保持できないんですね。
当然といえば当然なのですが…。
「外部ファイルに保存していって、パワーポイント出力する際に、そこから取り出すか?」「いやいや、プロットデータとかもあるからその辺良い感じに外部ファイルから取り出すこととかできるのか?」
とか試行錯誤しながら3時間たったころ、reactiveValuesという素敵なオブジェクトを見つけました。
reactiveValuesについては、公式サイトをご覧ください。
Shiny - reactiveValues
server.R
graph_output = reactiveValues()
としてgraph_outputというオブジェクトを作ります。
このオブジェクトには、
graph_output$a = 1 graph_output$b = 2
のように変数を追加することができます。
これを使って
observeEvent(input$add_plot, { ### add_plotというactionButtonトリガーが発動されたときの、更新処理を書いていく })
と、actionButtonによるトリガーをobserveEventで受け取って、その中で先程作ったreactiveValuesの性質を持つgraph_outputオブジェクトをどのように更新していくか、処理を書いていきます。
今回は、
observeEvent(input$add_plot, { ### 省略 graph_output$graph_list = c (graph_output$graph_list, graph_list) graph_output$input_graph_title = c (graph_output$input_graph_title, input_graph_title) })
のようにして、actionButton が押される度に、グラフデータと関連するグラフのタイトルをデータに追加する処理を書きました。
このように、あるトリガーに対して何か見た目を更新したりデータを上書き更新したりするのではなく、「追加」していくイメージのツールを作成したい場合は、reactiveValuesを使うと良いと思います!
もしかすると、もっと良い書き方があったかもしれません。
知っている方がいれば教えてください。
まとめと次回予定
当初No.1で作ってみた、Googleアナリティクスからデータ取得ツールを発展させる形でNo.4まで進めてきました。かなり実践的で、もう商品化できるレベルまでやってみたのですが、その分とっつきにくい内容でもあったかなと反省しています…。
そこでこの流れは一旦ストップし、次回からもう少し汎用的で基礎的な内容の話をできればと思います。
予定変わるかもですが、次回Shiny記事No.5は以下を公開予定です!
- ドラッグ&ドロップでデータを追加してグラフ化
お楽しみに!!