Shiny は R のパッケージの一つで、 このパッケージを使うと R を用いて対話的に操作する Web アプリケーションを作成することができます。Web 上のユーザーインタフェース部分を司る ui.Rと、内部動作を司る server.Rの二つの R 言語スクリプトで、サーバーサイドのコンテンツを作成できることが大きな特徴です。
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 二軸の散布図をプロットするプログラムです。
ui.Rを以下に示しました。個人的には ui.Rにデータセット iris 固有の情報が入ってしまって好ましくないと思っているのですが、汎用性の高いインターフェイス作成にはおいおい取り組んでいきますので、どうぞご容赦ください。
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な入出力の用法です。
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)
})
}
reactiveと renderPlotの濃密な関係
reactive関数は、ui.Rが表示する Web 画面上のウィジェット操作で変化する変数の値に対応(反応)する、表現式のオブジェクトを生成します。この例では、 ui.Rで変化する変数は input$varXと input$varYになります。
一方、renderPlot関数は server.Rで生成したプロットを ui.Rへ橋渡しする役目を担います。この例では output$plotに生成されたプロットが、ui.Rの plotOutput("plot") に反映されます。この renderPlot関数(正確には renderで始まる関数)内で生成されるプロットや文字列などで、reactive関数で生成した表現式のオブジェクトを扱うことができます。その際、表現式のオブジェクト名の右側に ()を付加します。この例では x→ x()といった具合です。
なぜ、このような一見面倒な仕組みが必要なのでしょうか。Shiny のコードを調べてはいませんが、おそらく Web アプリケーションを効率よく更新するために必要だからでしょう。ユーザーの操作でウィジェットの変数が変更された時に、その変数に関連したプロットのみを更新するような仕組みを導入しておかないと、複雑なプロットが数多く表示されているような画面では更新に時間が掛かってしまい、対話的にストレスなく使用することができなくなってしまいます。
参考サイト

にほんブログ村