この記事は Shiny 公式サイトのチュートリアルを翻訳したものです。
http://shiny.rstudio.com/tutorial/lesson4/
チュートリアル目次:http://d.hatena.ne.jp/hoxo_m/20151222/p1
LESSON4 "reactive" な出力の表示
「本物の」Shiny アプリを作る時が来ました。このレッスンでは、ユーザーがウィジェットを操作したときに、表示されたオブジェクトが変更されるようなコードを書いていきます。つまり、ユーザ入力に反応(reaction)するようなアプリを作っていきます。
"reactive"(反応的)な出力は、Shiny の最も大きな特徴の一つで、ユーザーとコミュニケートする強力な手段を与えてくれます。
このレッスンを終えると、2行の reactive なテキストを持った単純な Shiny アプリが完成します。各行にはユーザ入力に基づいたウィジェットの値が表示されます。
この新しいアプリのために、新しいフォルダを用意します。ワーキングディレクトリに census-app
という名前のフォルダを作成して下さい。このフォルダに、census-app
アプリのための ui.R
と server.R
を保存します。
reactive な出力のための2ステップ
reactive な出力を作成するために、次の2つのステップを実行していきましょう。
- ユーザーインターフェース(
ui.R
)に reactive な出力表示を追加する。 - 出力を構築するためのコードを
server.R
に書く。もし、そのコードにウィジェットの値が使われているならば、出力表示は reactive になる。
Step1: ユーザーインターフェースに reactive な出力表示を追加する
Shiny は reactive な出力表示を生成するための関数セットを、ユーザーインターフェース用に持っています。各関数は、特定の型の出力表示を生成します。
HTML タグやウィジェットと同様に、ui.R の sidebarPanel
か mainPanel
の内部にこれらの関数を配置します。
出力関数 | 生成物 |
---|---|
htmlOutput | HTML |
imageOutput | 画像 |
plotOutput | プロット |
tableOutput | 表 |
textOutput | テキスト |
uiOutput | HTML |
verbatimTextOutput | テキスト |
例えば、以下の ui.R
は、textOutput
を使って、reactive なテキストを mainPanel
に追加しています。
# ui.R
shinyUI(fluidPage(
titlePanel("censusVis"),
sidebarLayout(
sidebarPanel(
helpText("Create demographic maps with
information from the 2010 US Census."),
selectInput("var",
label = "Choose a variable to display",
choices = c("Percent White", "Percent Black",
"Percent Hispanic", "Percent Asian"),
selected = "Percent White"),
sliderInput("range",
label = "Range of interest:",
min = 0, max = 100, value = c(0, 100))
),
mainPanel(
textOutput("text1")
)
)
))
textOutput
は引数を1つ持つことに注意して下さい。ここでは text1
と入っています。各 *Output
関数は、引数を1つだけとります。この引数には、Shiny が reactive 要素として使うための名前を、文字列として入力します。
Step2: 出力を構築するためのコードを server.R に書く
ui.R
で出力を表示する準備はできました。次は出力を構築しましょう。
server.R
に reactive な出力を構築するコードを書いて、Shiny に何を行うべきかを教えましょう。コードは server.R
の shinyServer
に入力する無名関数の中に書きます。
この無名関数には特別な役割があります。それは output
というオブジェクトの構築です。output
はリストのような構造で情報を保持するオブジェクトです。この output
オブジェクトに、アプリ内で更新したい全ての出力要素を含めます。
無名関数内で output
に新しい要素を追加するには、下記のように書きます。要素の名前は ui.R
で生成した reactive な出力表示の名前と一致しなければなりません。
下記では、出力要素 output$text1
と出力表示 textOutput("text1")
の間で、要素名 text1
が一致していることが確認できると思います。
# server.R
shinyServer(function(input, output) {
output$text1 <- renderText({
"You have selected this"
})
}
)
無名関数のコードの最後で output
を返却する必要はありません。R は参照クラスのセマンティクスにより、自動的に output
を更新します。(※訳注:R5クラスを参考のこと)
output
に保持される出力要素は、Shiny の render*
関数の出力である必要があります。これらの関数は R の表現式を受け取り、前処理を行います。render*
関数を使うということは、reactive なオブジェクトを作っていることになります。
render 関数 | 生成物 |
---|---|
renderImage |
画像 (saved as a link to a source file) |
renderPlot |
プロット |
renderPrint |
print 出力 |
renderTable |
データフレーム、行列、または、他のテーブル状の構造 |
renderText |
文字列 |
renderUI |
Shiny タグオブジェクトまたは HTML |
各 render*
関数は {}
で囲まれた R の表現式を引数として受け取ります。上記のコードでは、表現式は単純な一行の文字列ですが、複数の行に渡ったり、もっと複雑な関数呼び出しを行うこともできます。
この R 表現式は、Shiny に与える指令書だと思ってください。Shiny は、まず最初に起動したときにこれらの命令を実行します。さらに、出力を更新するときにも再びこの命令列を実行します。
これが機能するためには、表現式はあなたが想定した通りのオブジェクトを返す必要があります(テキスト、プロット、データフレームなど)。表現式がオブジェクトを返さなかったり、想定外のオブジェクトが返されたりすると、エラーになるので注意してください。
ウィジェットの値を使う
この時点のコードで、Shiny アプリを起動してみましょう。メインパネルには "You have selected this" と表示されます。ただし、このテキストは reactive ではありません。このアプリのウィジェットを操作しても、このテキストは変更されません。
ウィジェットの値を使ってテキストを構築するように変更すれば、テキストは reactive になります。それではやり方を見てみましょう。
server.R
の最初の行を見てください。無名関数が input
と output
の二つの引数を持っていることがわかるでしょうか。output
はすでに見たように、リストのような構造で情報を保持する R オブジェクトです。
input
も output
と同じくリストのように扱えるオブジェクトであり、Shiny アプリ内のウィジェットの全ての値を保持します。ウィジェットの値は、ui.R
内で与えたウィジェットの名前で参照できます。
例えば、今回の census-app
は、二つのウィジェット "var" と "range" を持ちます。ウィジェット "var" と "range" の値は、input
オブジェクトの input$var
と input$range
に格納されています。スライダーウィジェットは 2 つの値(min と max)を持つので、input$range
は長さ 2 のベクトルとなります。
# server.R
shinyServer(
function(input, output) {
output$text1 <- renderText({
paste("You have selected", input$var)
})
}
)
Shiny はどの出力表示がどのウィジェットに依存しているかを知っています。ユーザがウィジェットを変更したとき、Shiny は、そのウィジェットに依存している全ての出力を、変更されたウィジェットの新しい値を使って再計算します。その結果、再構築された出力オブジェクトにより、出力表示は最新の状態になります。
これが、Shiny における reactive な出力の作り方です。これは、input
の値を output
オブジェクトに繋げることで実現されています。ウィジェットの値の変更の検知、依存する出力の再計算、再計算された出力を出力表示に反映という一連の複雑な仕事は、全て Shiny が自動的にやってくれます。
アプリを起動して reactive な出力を確認しよう
server.R
と ui.R
を上に書いてあるように変更して下さい。そして、コマンドラインに runApp(display.mode = "showcase")
と打ってアプリを起動して下さい。下図のようになったでしょうか? セレクトボックスの値を変更すると、テキストも変更されることを確認してください。
server.R
スクリプトに注目してください。Shiny が出力の再構築を行うたびに該当コードがハイライトされます。このハイライトは、Shiny が reactive な出力を生成している様子を可視化しています。
やってみよう
今回のアプリのメインパネルの 2 行目に reactive なテキストを追加してください。その行にはこう表示されます:"You have chosen a range that goes from something to something"。ただし、各 something には、スライダーウィジェットの min(最小値) と max(最大値) が入るようにしてください。
ui.R
と server.R
の両方のファイルを変更するのを忘れないように!
まとめ
このレッスンでは、初めての reactive な Shiny アプリを作りました。ここで学んだのは、
- reactive な出力表示を Shiny アプリで使うためには、
ui.R
で*Output
関数を使う - 出力オブジェクトを構築するためには、
server.R
でrender*
関数を使う -
render*
関数への入力は、{}
で囲んだ表現式を書く -
render*
で入力した表現式は、output
に保存され、アプリの reactive な出力表示となる - reactive な出力にするためには、
render*
に入力する表現式に、input
の値を含める
これらのルールに従えば、Shiny は自動的に出力を reactive にしてくれます。
レッスン 5 では、R スクリプトや外部データに依存する、より洗練された reactive アプリケーションを作っていきます。