※20180205 データフレームの取り扱いを変更
以下のようなイメージで同じ要素グループを連続して並べる時のコードです。それぞれのカタマリで個別のnumericInputを参照し、それぞれヒストグラムを描画しているデモです。
library(shiny)
# UI description
rep <- 5
ui <- fluidPage(
lapply(1:rep, function(i) {
div(
numericInput(paste0('n', i), paste0('num=', i), i ^ 2 * 100),
plotOutput(paste0('p', i))
)
})
)
# Server logic
server <- function(input, output, session) {
dflist <- list()
lapply(1:rep, function(i) {
output[[paste0('p', i)]] <- renderPlot({
dflist[[i]] <- rnorm(input[[paste0('n', i)]])
hist(dflist[[i]])
})
})
}
shinyApp(ui, server)
ポイント
for/whileは使用しないほうが良い
描画とreactivityの演算はループで指定した順番とは別で行われるため(データがステートレスにならなくてはいけない)、逐次を想定した記述をしてもうまくいきません。ステートレスということはlapplyでやりきれる、ということですので頑張ってlapplyで記述しましょう。生成数を動的に変更するためにinsertUIを使用した例はこちらで記述しています。
繰り返しに複数要素を入れ込むときはdivる
複数繰り返しはdiv()でくくりましょう。仮想的にクラス化されるshinydashboard::box みたいな関数でも同じことが実現できます。
div(
numericInput(paste0('n', i), paste0('num=', i), i ^ 2 * 100),
plotOutput(paste0('p', i))
)
異なるデータセットを使用する場合は親リスト以下にデータフレームを格納する
dflist <- list()
まずデータフレームを格納するリストを作成し
dflist[[i]] <- rnorm(input[[paste0('n', i)]])
その後それぞれのデータフレームをその下に格納していきます。ちなみにreactive contextに触れないようにisolateでくくるか、例のようにcontext外になるようplotの中に入れてしまうかする必要があります。