R Shiny:如何防止嵌套选择器重复更新绘图?

R Shiny: how to prevent duplicate plot update with nested selectors?

我有一个数据集,其中每一行包含有关单个人的数据,每一列包含有关 him/her 的不同信息。假设它看起来像这样(但实际数据中的列和行更多):

data <- data.frame(
  height=runif(1000, 150, 200),
  sex=sample(c("f","m"), 1000, replace=T),
  heir=sample(c("blond", "black", "red", "brown"), 1000, replace=T),
  eye=sample(c("blue", "green", "brown"to show histograms ), 1000, replace=T)
)

我想制作一个闪亮的应用程序,我可以在其中 select 一个类别(列)和一个值,并在共享该值的人中绘制 height 的直方图。例如对于 category = 'sex'value = 'f' 我想要一个女性身高的直方图。因为每个类别都有不同的值集,所以在更改类别后我必须(自动)更新值 select 或太。 问题是这意味着两次更新,每一次都生成新的直方图,而只有第二次才有意义。这是我的代码:

server.R

shinyServer(function(input, output, session) {
  
  data <- data.frame(
    height=runif(1000, 150, 200),
    sex=sample(c("f","m"), 1000, replace=T),
    heir=sample(c("blond", "black", "red", "brown"), 1000, replace=T),
    eye=sample(c("blue", "green", "brown"), 1000, replace=T)
    )
  
  # update value after category change
  observe({
    updateSelectInput(session, "value", "Value",
                      choices=as.list(levels(data[,input$category])))
    cat(paste("category update:",input$category, "\n"), file = stderr())
  })
  
  output$histogram <- renderPlot({
    cat(paste("hist:", "category =", input$category,
              "value =",input$value, "\n"), file = stderr())
    hist(data[data[, input$category] == input$value, "height"])
  })
})

ui.R

shinyUI(fluidPage(
  sidebarPanel(    
    selectInput("category", "Category", choices=c("sex", "heir", "eye"), selected="sex"),
    selectInput("value", "Value", c("f", "m"), selected="f")
  ),
  
  mainPanel(
    plotOutput("histogram")
  )
))

cat 表达式可以更轻松地查看正在发生的事情。当我 运行 应用程序时,默认类别 ('sex') 和值 ('f') 是 selected,所以控制台输出是:

category update: sex 
hist: category = sex value = f 

然后,当我使用 select 或者,例如继承人选择不同的类别时,我得到了一个信息:

category update: heir 
hist: category = heir value = f 
Error in hist.default(data[data[, input$category] == input$value, "height"]): 
  invalid number of 'breaks'
hist: category = heir value = black 

因此,首先,该应用会更改类别并尝试为新 category = heir 和旧 value = f 绘制直方图,这当然会失败。只有这样它才会改变 value 然后绘制正确的直方图。 有什么方法可以自动更新 value select 或者在绘制任何绘图之前?

您可以使用 isolate 来避免直方图依赖于 input$category:

  output$histogram <- renderPlot({
    cat(paste("hist:", "category =", isolate(input$category),
              "value =",input$value, "\n"), file = stderr())
    hist(data[data[, isolate(input$category)] == input$value, "height"])
  })

当类别更改时,您的直方图将不再更新。更改类别也会更改您应用中的值,并且当该值更改时直方图将更新。

有关 isolate here 的更多信息。