【问题标题】:R Shiny plot updates in two steps instead of oneR Shiny 情节更新分两步而不是一步
【发布时间】:2023-04-04 04:57:02
【问题描述】:

R Shiny 应用由两个输入组成。输出图的用户过滤数据选择的值。

第二个输入的选择取决于第一个输入。

例如,A 公司有 2019-2017 年的数据,B 公司有 2018-2017 年的数据。 用户首先选择一家公司,然后更新第二个输入以仅显示给定公司可用的年份。

在下面的示例中,当用户从 B 公司更改为 A 公司时,情节会分两步更新(我在 gif 中显示)。第一步只持续几分之一秒,但对用户可见。

这很可能是因为 R Shiny 应用首先显示公司 A x 2018 对的直方图,然后更新年份并显示公司 A x 2019。

有没有办法避免 R Shiny 显示公司 A x 2018 数据的中间步骤?

这可以通过操作按钮解决,但需要用户付出额外的努力。

例子:

library(shiny)
library(tidyverse)

# Dummy data - company A has year 2019-2017, company B has 2018-2017
company.a <- data.frame(
    company = "A",
    year = rdunif(10000, 2019, 2017),
    value = rnorm(10000)
)
company.b <- data.frame(
    company = "B",
    year = rdunif(1000, 2018, 2017),
    value = rnorm(1000)
)
data <- rbind(company.a, company.b)

# Year choices when the app starts
year.choices <- data %>% 
    filter(company == unique(data$company)[1]) %>% 
    select(year) %>% 
    arrange(desc(year)) %>% 
    unique() %>% 
    pull()

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            selectInput("company", "Choose company:", choices = unique(data$company)),
            selectInput("year", "Choose year:", choices = year.choices)
        ),
        mainPanel(plotOutput("distPlot"))
    )
)

server <- function(input, output, session) {
    # The list of years gets updated when the user changes company
    observeEvent(input$company, { 
        year.choices <- data %>% 
            filter(company == input$company) %>% 
            select(year) %>% 
            arrange(desc(year)) %>% 
            unique() %>% 
            pull()
        updateSelectInput(session, "year", choices = year.choices)
    })

    # Plot for the chosen company and year
    output$distPlot <- renderPlot({
        plot.data <- data %>% filter(company == input$company & year == input$year) %>% select(value) %>% pull()
        hist(plot.data)
    })
}

shinyApp(ui = ui, server = server)

动图: Gif showing that R Shiny updates plot in two steps

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    我认为您可以简单地将input$company 隔离在renderPlot 中:

    output$distPlot <- renderPlot({
        plot.data <- data %>% filter(company == isolate(input$company) & year == input$year) %>% select(value) %>% pull()
        hist(plot.data)
    })
    

    确实,虽然input$company 是孤立的,但renderPlot 仍将对input$company 的更改做出反应,因为此类更改会触发input$year 的更改。

    【讨论】:

    • 确实,这个解决方案在这个例子中就像一个魅力。但是,如果我创建类似于 A:company.c &lt;- company.a 的公司 C 并将其添加到数据 data &lt;- rbind(company.a, company.b, company.c),则当从公司 C 到公司 A 时,这种方法会阻止绘图更新。
    猜你喜欢
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 2021-12-03
    相关资源
    最近更新 更多