我正在尝试使用几个选项卡构建一个Shiny应用程序。其中一个标签页供用户选择基础数据集,我希望此数据可以在另一个标签中显示为漂亮的图形。 (我将基础数据保存在最大大小的文件中,以便用户一次可以调查一个文件,因为我担心,否则Shiny应用程序可能会变得非常缓慢甚至崩溃)。但是,我正在努力更新包含基础数据的变量,如下面简化得多的可重现示例所示:
library(shiny)
library(shinyWidgets)
library(dplyr)
library(ggplot2)
dataFrameA <- data.frame(
company = c("A", "B", "C", "D"),
revenue = runif(4, min = 0, max = 1000000)
)
dataFrameB <- data.frame(
company = c("E", "F", "G", "H"),
revenue = runif(4, min = 0, max = 1000000)
)
usedDataFrame <- dataFrameA
ui <- fluidPage(
verticalTabsetPanel(
verticalTabPanel(
title = "graph", icon = icon("chart-bar", "fa-1x", lib = "font-awesome"),
box_height = "120px",
plotOutput(outputId = "barChart")
),
verticalTabPanel(
title = "data", icon = icon("database", "fa-1x", lib = "font-awesome"),
box_height = "120px",
selectInput(inputId = "selectData", label = "choose dataset",
choices = c("ABCD", "EFGH"))
)
)
)
server <- function(input, output){
output$barChart <- renderPlot({
ggplot(data = usedDataFrame, aes(x = company, y = revenue)) +
geom_bar(width = 1, stat = "identity")
})
observeEvent(input$selectData, {
if (input$selectData == "ABCD"){
usedDataFrame <- dataFrameA
}else{
usedDataFrame <- dataFrameB
}
})
}
shinyApp(ui = ui, server = server)
您将看到,尽管用户在“数据”选项卡中选择了不同的数据集,“图形”选项卡中的图形也没有改变。但是,我期望它会发生变化,因为下面的watchEvent块更改了图形所基于的全局变量usedDataFrame。任何人都可以向我暗示我的上述假设是错误的,还是指出一种更新基础数据集的更明智的方式?简单的解释将对您有所帮助(我没有技术背景)。
答案 0 :(得分:1)
您非常接近您的方法,但是使用reactive
会比您处理input
来自动更新,因此比处理全局变量更容易的方法。
library(shiny)
library(shinyWidgets)
library(dplyr)
library(ggplot2)
dataFrameA <- data.frame(
company = c("A", "B", "C", "D"),
revenue = runif(4, min = 0, max = 1000000)
)
dataFrameB <- data.frame(
company = c("E", "F", "G", "H"),
revenue = runif(4, min = 0, max = 1000000)
)
ui <- fluidPage(
verticalTabsetPanel(
verticalTabPanel(
title = "graph", icon = icon("chart-bar", "fa-1x", lib = "font-awesome"),
box_height = "120px",
plotOutput(outputId = "barChart")
),
verticalTabPanel(
title = "data", icon = icon("database", "fa-1x", lib = "font-awesome"),
box_height = "120px",
selectInput(inputId = "selectData", label = "choose dataset",
choices = c("ABCD", "EFGH"))
)
)
)
server <- function(input, output){
dat <- reactive({
if (input$selectData == "ABCD") {
return(dataFrameA)
}
else if (input$selectData == "EFGH") {
return(dataFrameB)
}
})
output$barChart <- renderPlot({
ggplot(data = dat(), aes(x = company, y = revenue)) +
geom_bar(width = 1, stat = "identity")
})
}
shinyApp(ui = ui, server = server)
答案 1 :(得分:1)
output$barChart
是反应性端点。修改代码的最简单方法是直接使用反应性源input$selectData
。每当输入更改时,您的输出将被通知需要重新执行。
它看起来像这样:
output$barChart <- renderPlot({
if (input$selectData == "ABCD"){
usedDataFrame <- dataFrameA
}else{
usedDataFrame <- dataFrameB
}
ggplot(data = usedDataFrame, aes(x = company, y = revenue)) +
geom_bar(width = 1, stat = "identity")
})
您根本不需要observeEvent
。
另一种方法是,您可以使usedDataFrame
处于反应状态,然后从您的renderPlot
进行呼叫:
usedDataFrame <- reactive({
if (input$selectData == "ABCD"){
dataFrameA
}else{
dataFrameB
}
})
output$barChart <- renderPlot({
ggplot(data = usedDataFrame(), aes(x = company, y = revenue)) +
geom_bar(width = 1, stat = "identity")
})