Np-Urのデータ分析教室

オーブンソースデータなどWeb上から入手できるデータを用いて、RとPython両方使って分析した結果を書いていきます

【Shiny100本ノック No.3】ggplotグラフをインタラクティブに作成してPowerPointダウンロードまで行う

Shiny100ノックもなんと今回で3回目。
2回で挫折するかと思いましたが、皆様の応援もあってあと4回くらいは続けられそうです。

さて、前回と前々回ではGoogleアナリティクスのデータをAPI経由で取得して、グラフ可視化するところまでやりました。
www.randpy.tokyo
www.randpy.tokyo

しかし、Shinyの魅力といえばインタラクティブなところ。
UI側で、グラフの色や装飾など柔軟に変更して、それを元に即座にグラフ出力してみましょう。

そしてせっかくなので、作ったグラフをPowerPointにて手元にダウンロードしてみます。
ファイルダウンロードに関しては、以下で簡単に説明しているので、そちらをご覧ください。
www.randpy.tokyo

ここまでくれば、Web担当者の悩みの一つである「アクセス解析の報告書」を作るところまで自動化できます!

グラフの見た目を変更してみる

簡単なコードを作って、感覚をつかみましょう。
データはお馴染みのirisを使います。

完成イメージ図としては、以下のようです。Irisから出力したい列と色を指定してプロットできるようにしましょう。
f:id:Np-Ur:20170825144216p:plain
f:id:Np-Ur:20170825144221p:plain

コードは以下の通りです。
ui.R

library(shiny)

shinyUI(
  
  fluidPage(    
    selectInput("sel",label = "col",choices = colnames(iris)[2:4]),
    selectInput("color",label = "col",choices = c("red", "black", "blue", "green")),
    plotOutput("plot")
  )
)

server.R

library(shiny)
library(ggplot2)

shinyServer(function(input, output,session) {
  output$plot = renderPlot({
    data = data.frame(x = iris[,input$sel], y = iris$Sepal.Length)
    g = ggplot(data, aes(x = x, y = y))
    g = g + geom_point(colour=input$color)
    print(g)
  })
})


ui.Rから見ていきましょう。
1つ目のselectInputにてプロットするirisのデータを選択し、2つ目のselectInputにてプロットする色を選択しています。

送られてきた情報を、そのまま

data = data.frame(x = iris[,input$sel], y = iris$Sepal.Length)

g = g + geom_point(colour=input$color)

にて受け取ってそのままggplotにて出力しているだけです。

はいー簡単ですね!Shiny様ありがとうございます。

作ったグラフをPowerPointにて出力する

それでは、次にPowerPoint出力を行うところをやりましょう。
github.com
こちらにもコードを掲載していますが、直貼りしちゃいます。

ui.R

library(shiny)
library(rJava)
library(ReporteRsjars)

shinyUI(
  
  fluidPage(    
    selectInput("sel",label = "col",choices = colnames(iris)[2:4]),
    selectInput("color",label = "col",choices = c("red", "black", "blue", "green")),
    plotOutput("plot"),
    downloadButton('downloadData', 'Download')
  )
)

server.R

library(shiny)
library(DT)
library(ReporteRs)
library(rJava)
library(ggplot2)

shinyServer(function(input, output,session) {
  
  output_plot_fun = function(){
    data = data.frame(x = iris[,input$sel], y = iris$Sepal.Length)
    ggplot(data, aes(x = x, y = y)) + geom_point(colour=input$color)
  }

  output$plot = renderPlot({
    print(output_plot_fun())
  })
  
  output$downloadData = downloadHandler(
    filename = "testfile.pptx",
    content = function(file) {
      doc = pptx( )
      
      #Slide 1
      doc = addSlide(doc, "Title Slide")
      doc = addTitle(doc,"Rから作ったパワポです")
      doc =  addSubtitle(doc, "皆さん使ってね")
      
      #Slide 2
      doc = addSlide(doc, "Title and Content")
      doc = addTitle(doc, "2ページ目")
      doc = addPlot(doc, fun = print, x = output_plot_fun() ) 
      writeDoc(doc,file)
    }
  )
})

必要なライブラリがいくつかあるので、事前に

install.packages("ReporteRs")

などで読み込んであげましょう。

1点注意点が。今回ReporteRsというパワーポイント出力のためのライブラリを使っていますが、そのためにはrJavaというライブラリもインストールしておく必要があります。
参考:ReporteRs Github

もちろんrJavaなので、お使いのパソコンにJavaの環境がある必要があります。64bitなら64bit用のJavaを事前にパソコンにいれておくようにしましょう。
僕はそこに引っかかって何度かエラーに苦しみました…。

ReporteRs の書き方はとても直感的なので、何も説明はいらないかもしれませんね。
基本的には、

doc = pptx( )

と呼び出したあとは、

  • addSlide
  • addTitle
  • addSubtitle
  • addPlot

のように追加していくことでスライドを作ることができます。

今回グラフ以外の部分(タイトルなど)は、server.R側ですべて決めていますが、UI側で入力してあげると良いですね。それでこそShinyって気がします。

addPlotの部分もggplot2グラフを出力する際は、fun引数に"print"、x引数に作成したggplot2を与えあげればOKです。

実際にコードを動かして、ダウンロードしてみてください!

下のような2枚のパワポスライドが完成しているはずです。
f:id:Np-Ur:20170825170040p:plain
f:id:Np-Ur:20170825170043p:plain
きっと「おーー本当にできてる!」と感動するはずです笑

まとめ

今回は、Shiny上で色を自由に変えながらグラフ出力と、そのグラフを元にパワーポイントを作りダウンロードする、という実践をしてみました。
前回・前前回と行った、API経由でのデータ取得とグラフ出力と合わせれば、あんなことからこんなことまで…様々なことができそうですね!

ということで、次回のShiny100ノック(No.4)では、No.1 ~ No.3をつなぎ合わせて、
「もうこれ売れんじゃない?」というデータ可視化&スライド出力ツールを作ってみましょう。

掛け合わせているだけなので、新しい勉強にはならないかもしれませんが、「ツール」と呼べる代物まで昇華できることは大きなモチベーションになると思います。
お楽しみに!!



8月30日追記
N0.4 公開しました。
www.randpy.tokyo