はじめに
- RのShinyのisolateの理解があいまいだったので、いろいろ触ってみた
isolateを使うケース
- あるインプット値を変更したときに、即座にそれがoutputに影響してほしくないとき
- あるインプット値を変更した時に、別のinput(action)を入力したときにだけoutputに影響してほしいとき
イメージ図
- Stop reactions with isolate() がわかりやすい
コード:うまく動くケース
1で、input$goButtonをひも付ける。2で、isolate()で紐付けたいところを囲む
library(shiny)
ui <- fluidPage(
headerPanel("isolateのテスト"),
sidebarPanel(
sliderInput("obs", "Number of observations:",
min = 0, max = 1000, value = 500),
actionButton("goButton", "Go Button", icon("refresh"))
),
mainPanel(
plotOutput("distPlot")
)
)
server <- function(input, output, session) {
output$distPlot <- renderPlot({
# 1. input$goButtonをrenderPlotのトリガーとして紐付ける
input$goButton
# 2. トリガーがあれば、input$obsの値をもとに変更
dist <- isolate(rnorm(input$obs))
hist(dist)
})
}
shinyApp(ui, server)
コード:うまく動かないケース1
input$goButtonを削除した場合は、ひも付けがないので、何をしてもdistが変わらないのでヒストグラムの結果は変わらない
library(shiny)
ui <- fluidPage(
headerPanel("isolateのテスト"),
sidebarPanel(
sliderInput("obs", "Number of observations:",
min = 0, max = 1000, value = 500),
actionButton("goButton", "Go Button", icon("refresh"))
),
mainPanel(
plotOutput("distPlot")
)
)
server <- function(input, output, session) {
output$distPlot <- renderPlot({
# 変更されない
dist <- isolate(rnorm(input$obs))
hist(dist)
})
}
shinyApp(ui, server)
コード:うまく動かないケース2
isolate()がない場合は、input$obsを変更しても、input$goButtonを変更しても、histの表示が変わってしまう
library(shiny)
ui <- fluidPage(
headerPanel("isolateのテスト"),
sidebarPanel(
sliderInput("obs", "Number of observations:",
min = 0, max = 1000, value = 500),
actionButton("goButton", "Go Button", icon("refresh"))
),
mainPanel(
plotOutput("distPlot")
)
)
server <- function(input, output, session) {
output$distPlot <- renderPlot({
# input$goButtonをrenderPlotのトリガーとして紐付ける
input$goButton
dist <- rnorm(input$obs)
hist(dist)
})
}
shinyApp(ui, server)
コード:うまく動かないケース3
isolate()とinput$goButtonを削除した場合は、ひも付けもないので、input$goButtonの意味もなく、input$obsを変更したときだけhistの表示が変わる
library(shiny)
ui <- fluidPage(
headerPanel("isolateのテスト"),
sidebarPanel(
sliderInput("obs", "Number of observations:",
min = 0, max = 1000, value = 500),
actionButton("goButton", "Go Button", icon("refresh"))
),
mainPanel(
plotOutput("distPlot")
)
)
server <- function(input, output, session) {
output$distPlot <- renderPlot({
dist <- rnorm(input$obs)
hist(dist)
})
}
shinyApp(ui, server)
isolateのその他
input$goButton
上記の意味は以下と同じ意味。input$goButtonをクリックすると1が返り、続きのrenderPlotが実行される。ただし、appをはじめに起動したときは描画されなくなる
if (input$goButton == 0)
return()
参考のStop reactions with isolate()とおりだが、複数のinputでの対応も下記のように書けるみたい
# Separate calls to isolate
x <- isolate({ input$xSlider }) + 100
y <- isolate({ input$ySlider }) * 2
z <- x/y
# Single call to isolate
isolate({
x <- input$xSlider + 100
y <- input$ySlider * 2
z <- x/y
})
# Single call to isolate, use return value
z <- isolate({
x <- input$xSlider + 100
y <- input$ySlider * 2
x/y
})
おわりに
isolate()はよくわかったが、reactive()とobserve()の理解もあやしいので次はそれを試してみる予定