2018-09-18

R Shiny を使ってみる (2)

Shiny は R のパッケージの一つで、 このパッケージを使うと R を用いて対話的に操作する Web アプリケーションを作成することができます。Web 上のユーザーインタフェース部分を司る ui.R と、内部動作を司る server.R の二つの R 言語スクリプトで、サーバーサイドのコンテンツを作成できることが大きな特徴です。

参考サイト [1] より引用

RStudio 上で Shiny による Web アプリケーションを作り始めたので、理解したことを備忘録としてまとめたことを不定期に紹介していきます。

本記事で使用している動作環境は次の通りです。

  • OS: Fedora 28 (x86_64)
  • R: R-core-3.5.0-4.fc28.x86_64, R-core-devel-3.5.0-4.fc28.x86_64
  • RStudio: rstudio-1.1.456-1.x86_64

自分が R を使って解析したい特定の分野について、Web アプリケーションを作成し、参考サイト [2] にある Shiny Server を Linux で稼働させて、作った Web アプリケーションを利用できるようにすることが目標です。しかし現時点では、その Web アプリケーションを作るだけの知識が伴っていないので、しばらくの間、簡単なサンプルで試行錯誤を続けて、判ったことをまとめていきたいと思います。

Web App の作成 : Iris explorer

まずはベースとなるサンプルプログラムを iris データを用いて作ってみました。名づけて Iris explorer です。sepal(花びらの「がく」)、petal(花弁)の Length(長さ)と Width(幅)を選んで X-Y 二軸の散布図をプロットするプログラムです。

Iris explorer の実行例

ui.R を以下に示しました。個人的には ui.R にデータセット iris 固有の情報が入ってしまって好ましくないと思っているのですが、汎用性の高いインターフェイス作成にはおいおい取り組んでいきますので、どうぞご容赦ください。

リスト:ui.R 
library(shiny)

fluidPage(
  titlePanel("Iris explorer"),
  sidebarLayout(
    sidebarPanel(
      selectInput(
        inputId = "varX",
        label = "Select the X variable",
        choices = c("Sepal.Length" = 1, "Sepal.Width" = 2, "Petal.Length" = 3, "Petal.Width" = 4)),
      selectInput(
        inputId = "varY",
        label = "Select the Y variable",
        choices = c("Sepal.Length" = 1, "Sepal.Width" = 2, "Petal.Length" = 3, "Petal.Width" = 4), selected = 2)
    ),
    mainPanel(
      plotOutput("plot")
    )
  )
)

server.R を下記に示しました。今回のポイントは reactive な入出力の用法です。

リスト:server.R 
library(shiny)
library(ggplot2)

gtheme <- theme(
  axis.title = element_text(size = 16),
  axis.text = element_text(size = 16),
  axis.line = element_line(),
  legend.title =  element_text(size = 14),
  legend.text = element_text(size = 14),
  panel.grid.major = element_line(colour="grey",size = rel(0.5)), 
  panel.grid.minor = element_blank(), 
  panel.background = element_rect(fill = "whitesmoke")
)

function(input, output) {
  x <- reactive(iris[, as.numeric(input$varX)])
  y <- reactive(iris[, as.numeric(input$varY)])
  xl <- reactive(names(iris[as.numeric(input$varX)]))
  yl <- reactive(names(iris[as.numeric(input$varY)]))
  
  output$plot <- renderPlot({
    p <- ggplot(iris, aes(x = x(), y = y(), colour = Species))
    p <- p + xlab(xl()) + ylab(yl()) + geom_point(size = 4)
    p <- p + gtheme
    plot(p)
  })
}

reactiverenderPlot の濃密な関係

reactive 関数は、ui.R が表示する Web 画面上のウィジェット操作で変化する変数の値に対応(反応)する、表現式のオブジェクトを生成します。この例では、 ui.R で変化する変数は input$varXinput$varY になります。

一方、renderPlot 関数は server.R で生成したプロットを ui.R へ橋渡しする役目を担います。この例では output$plot に生成されたプロットが、ui.R の plotOutput("plot") に反映されます。この renderPlot 関数(正確には render で始まる関数)内で生成されるプロットや文字列などで、reactive 関数で生成した表現式のオブジェクトを扱うことができます。その際、表現式のオブジェクト名の右側に () を付加します。この例では xx() といった具合です。

なぜ、このような一見面倒な仕組みが必要なのでしょうか。Shiny のコードを調べてはいませんが、おそらく Web アプリケーションを効率よく更新するために必要だからでしょう。ユーザーの操作でウィジェットの変数が変更された時に、その変数に関連したプロットのみを更新するような仕組みを導入しておかないと、複雑なプロットが数多く表示されているような画面では更新に時間が掛かってしまい、対話的にストレスなく使用することができなくなってしまいます。

参考サイト

  1. Shiny - RjpWiki
  2. Download Shiny Server - RStudio

 

ブログランキング・にほんブログ村へ
にほんブログ村

0 件のコメント: