Np-Urのデータ分析教室

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

R ShinyのtabsetPanelを使って複数のタブを持つページを作る

本記事は、Shiny Advent Calendar 2017の5日目の記事です。



Shiny100本ノック、第8回目となります。

Shiny100本ノックの前に「そもそもShinyってなんだよ」という方は以下を読んでみてください。
www.randpy.tokyo

前回は、navbarPageメソッドを使って複数ページへのリンクを持つナビゲーションバーを作成しました。
www.randpy.tokyo

今回はそれと若干似ているのですが、1つのページ内複数タブを持ち、表示を柔軟に切り替える、ということをやってみます。

前回同様、Shiny側で用意してくれているメソッドを使って簡単に実現させましょう。

複数タブをShinyアプリの完成形イメージ

今回は、以下のようなアプリを作ることが目標です。
f:id:Np-Ur:20171202162404p:plain

「Plot」をクリックすると、サイドバーで設定した値を元にヒストグラムをプロットしてくれます。
また、「Table」をクリックすると、ヒストグラム作成の元になったデータをテーブル形式で表示してくれます。

プロットとテーブルを縦に並べるとかなり見づらいUIとなってしまいますが、タブを使うことでスッキリしたUIになっています。

こんなスッキリUIですが、ShinyのtabsetPanelというメソッドを使うことで、簡単に実装可能です!

tabsetPanelのサンプルコード

まず早速サンプルコードを紹介します。

server.R

library(shiny)

shinyServer(function(input, output) {
  
  output$distPlot <- renderPlot({
    
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
  
  output$table <- renderTable({
    faithful[, 2]
  })
})

そして、ui.R

library(shiny)

shinyUI(navbarPage("tabsetPanel サンプル",
                   tabPanel("ページ1",sidebarLayout(
                     sidebarPanel(
                       sliderInput("bins",
                                   "Number of bins:",
                                   min = 1,
                                   max = 50,
                                   value = 30)
                     ),
                     mainPanel(
                       tabsetPanel(type = "tabs",
                                   tabPanel("Plot", plotOutput("distPlot")),
                                   tabPanel("Table", tableOutput("table"))
                       )
                    )
                   )),
                   tabPanel("ページ2",
                            h2("何か適当なテキスト")),
                   navbarMenu("自己紹介",
                              tabPanel("名前",
                                       h2("私の名前はNp-Urです。")
                              ),
                              tabPanel("好きな食べ物",h2("私は寿司が好きです。"))
                   )
))

まず、どんなページが作れるのか確認したい、という方は上記コードをそのまま貼れば動くはずなので実行してみてください。

tabsetPanelの使い方

実装方法はとてもシンプルで、タブを使いたい場所で、

tabsetPanel(type = "tabs",
  tabPanel("subtitle1", ~~),
  tabPanel("subtitle2", ~~)
)

このように書けばOkです。

subtitle1やsubtitle2という部分は以下の部分と対応しています。
f:id:Np-Ur:20171202164402p:plain

そして、「~~」という部分に具体的な表示したい内容を書く、という流れです。
特別プロットやテーブルを表示しなくても、

tabsetPanel(type = "tabs",
  tabPanel("subtitle1", h2("テキスト")),
)

こんな風にh2のテキストを表示することもできます。

なお、「type = "tabs"」という箇所は、「type = "pills"」と書くこともできます。
pillsにすると、タブの形式が以下のように変化します。
f:id:Np-Ur:20171202165006p:plain

個人的には、「type = "tabs"」の方がいかにもタブっぽいUIで好きです。まあこの辺は好みで変えてみてください。

navbarPageとの併用ももちろん可能

気付いた方もいるかもしれませんが、今回紹介したコードでは、前回使ったnavbarPageメソッドも使っています。
navbarPageの中の一つ目のtabPanelの中でtabsetPanelを使い、その中で更にtabPanelを使っている、という構造です。

つまり、色々省略すると以下の構造を持っていることになります。

navbarPage("title",
  tabPanel("", 
    tabsetPanel(type = "tabs",
      tabPanel("", ~~),
      tabPanel("", ~~)
    )
  ),
  tabPanel("", ~),
  navbarMenu("",
    tabPanel("", ~),
    tabPanel("", ~)
)

このような併用はもちろん可能なので、色々組み合わせてリッチなアプリケーションに進化させてみてください。

まとめ

今回は、1つのページに中で表示を切り替えるための、tabsetPanelメソッドを紹介しました。

そのまま表示してしまうと情報量が多すぎて見づらくなってしまう部分も、タブを効果的に使うことでユーザーに優しいUIに変えることができます。

また、複数のメソッドを組み合わせることで、たった数行コードを追加するだけなのに、とてもアプリケーションらしい見たい目に進化します。

是非色々試してみて、オリジナルのShinyアプリケーション制作に役立ててみてください!