本記事は、R Shiny Advent Calendar 2017の14日目の記事です。
Shiny100本ノック第15弾です。
前回は、ShinyからGoogle スプレッドシートにアクセスするアプリケーションを作成しました。
www.randpy.tokyo
Googleアカウントと連携する必要があるのですが、前回はShinyを立ち上げた後でアプリケーション上で認証を行うという方法を取りました。
これは何人かでアプリケーションを共有する際に、各ユーザーごとにそれぞれのGoogleアカウントを使えた方が便利だろうという判断で、このような実装にしました。
しかし、例えば共有Googleアカウント内のファイルから操作できれば良い、ということもあるかと思います。
その時は、Shinyを立ち上げる前にローカル上で、ShinyからGoogle スプレッドシートにアクセスするための認証情報を取得しておき、それを全員が用いるということにすれば簡単です。
実装もかなり簡略化できます!
ということで、今回はローカル上で一度Google連携を認証しておき、その認証情報を元にserver.R内で連携を行うアプリケーションを作ってみます。
ローカルで認証を行う
前回は、Google APIの設定も行う必要があってかなり面倒でしたが、今回はそれも要りません!まず下記を実行してください。
library(googlesheets) shiny_token <- gs_auth()
すると、Googleアカウントとの連携画面に飛ぶので、連携したいアカウントを選択してください。
その後、コンソール上に戻り、
saveRDS(shiny_token, "shiny_app_token.rds")
として先ほど取得した認証情報を保存しておいてください。
なおこの保存先は、これから作成するui.Rとserver.Rと同じディレクトリにしてください。
server.Rとui.Rのソースコード
server.Rとui.Rのスクリプトを紹介します。といっても前回の内容をかなり簡略したコードとなるので、解説は不要かもしれません。
server.R
##server.R library(shiny) library(googleAuthR) library(googlesheets) library(plyr) library(dplyr) library(DT) googlesheets::gs_auth(token = "shiny_app_token.rds") shinyServer(function(input, output, session) { output$table <- DT::renderDataTable({ tmp_data = gs_read(gs_title(input$file_name), ws = as.integer(input$sheet_id)) return(tmp_data) }) output$allfile <- renderTable({ read_data = gs_ls() return(read_data) }) })
ui.R
## ui.R library(shiny) library(DT) shinyUI(fluidPage(#theme = shinytheme("cerulean"), titlePanel("Google Spread sheet"), sidebarLayout( sidebarPanel( textInput('file_name','ファイル名'), br(), selectInput('sheet_id','sheet',choices = c(1:26)) ), mainPanel( tabsetPanel( tabPanel("file一覧", tableOutput("allfile")), tabPanel("Table", DT::dataTableOutput("table")) ) ) ) ))
コード解説
ui.Rに関しては、前回とはログインボタン・ログアウトボタンがごっそり無くなりました。server.Rに関しては、
googlesheets::gs_auth(token = "shiny_app_token.rds")
この一文で、先ほどローカルで取得した認証情報を読み込んで、googlesheetsライブラリに渡しています。
この部分が最も重要なところです。
また前回は
output$table <- DT::renderDataTable({ tmp_data <- with_shiny(f = gs_read, shiny_access_token = access_token(), gs_title(input$file_name), ws = as.integer(input$sheet_id)) return(tmp_data) })
のように、with_shinyメソッドに認証情報と一緒にgooglesheetsライブラリによるリクエスト文を書いていましたが、ここも要らなくなり以下のようにスッキリすることができました。
output$table <- DT::renderDataTable({ tmp_data = gs_read(gs_title(input$file_name), ws = as.integer(input$sheet_id)) return(tmp_data) })
全体的にserver.Rもui.Rもコード量が減り、また分かりやすくなりました。
終わりに
今回は、前回行ったShinyからスプレッドシートにアクセスする方法の番外編ということで、ローカル上で事前にGoogleアカウントと連携する方法について紹介しました。前回よりも汎用性は低くなりますが、設計がスッキリするのと、それに伴い書くべきプログラムの量がグンと減るのはメリットがかなり大きいのではと思います。
冒頭でも書きましたが、一つの共有アカウントをいじる場合であれば、こちらの方が良いですね。是非参考にしてみてください。