为什么我的 reactiveVal 代码在 R Shiny 中失败,而相同的代码在反应的一部分时有效?

Why does my reactiveVal code fail in R Shiny when the same code works when part of a reactive?

当用户 select 使用日期范围输入日期时,我想转换他们 select 日期的格式,然后将其视为字符。

当我的代码嵌入到一个更大的反应器中以过滤我的数据集时,我可以让它工作,但我无法让它工作,因为它有自己的价值。因为我需要在我的应用程序的许多区域使用这个字符串,所以我宁愿只编写一次代码,因为它是自己的 reactiveVal,而不是必须将它嵌入到更大的 reactives 中。

这是失败的代码(我只将 from_date 移到了较大的反应之外):

library(shiny)
library(dplyr)
library(tidyr)
library(htmltools)
library(lubridate)
library(DT)
library(stringr)



ui = fluidPage(
    useShinyjs(),
    useShinydashboard(),
    tabsetPanel(
        tabPanel("Resource View", fluid = TRUE,
                 sidebarLayout(
                     sidebarPanel(
                         div(id = "inputs",
                             dateRangeInput(
                                 inputId = "date_filter",
                                 label = "Filter by Month and Year",
                                 start = today(),
                                 end = (today() + 90),
                                 min = "Apr-2021",
                                 max = NULL,
                                 format = "M-yyyy",
                                 startview = "month",
                                 weekstart = 0,
                                 language = "en",
                                 separator = " to ",
                                 width = NULL,
                                 autoclose = TRUE
                             ),
                             br()),
                     ),
                     mainPanel(
                         DT::DTOutput("resource_table"),

                     )
                 )
        )
        )
    )
server = function(input, output, session) {
    
    from_date <- reactiveVal({ tibble(date = as.character(input$date_filter[1]))
    
    
    from_date <- from_date %>%
        mutate(date = str_remove_all(date, "-..$")) %>%
        separate(date, into = c("year", "month"), sep = "-") %>%
        mutate(month = case_when(
            month == "01" ~ "jan",
            month == "02" ~ "feb",
            month == "03" ~ "mar",
            month == "04" ~ "apr",
            month == "05" ~ "may",
            month == "06" ~ "jun",
            month == "07" ~ "jul",
            month == "08" ~ "aug",
            month == "09" ~ "sep",
            month == "10" ~ "oct",
            month == "11" ~ "nov",
            month == "12" ~ "dec",
            TRUE~ "ERROR"
        )) %>%
        unite("month_year", c(month, year), sep = "_")
    
    from_date <- parse_character(from_date$month_year)
    })
    
    
    select_values <- reactive({
        data <- tibble(employee = c("Justin", "Corey","Sibley", "Justin", "Corey","Sibley", "Lisa", "NA"),
                       education = c("graudate", "student", "student", "graudate", "student", "student", "nurse", "doctor"),
                       fte_max_capacity = c(1, 2, 3, 1, 2, 3, 4, 5),
                       project = c("big", "medium", "small", "medium", "small", "small", "medium", "medium"),
                       aug_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       sep_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       oct_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       nov_2021 = c(1, 1, 1, 1, 1, 1, 2, 5))
        

        
        
        
        to_date <- tibble(date = as.character(input$date_filter[2]))
        
        to_date <- to_date %>%
            mutate(date = str_remove_all(date, "-..$")) %>%
            separate(date, into = c("year", "month"), sep = "-") %>%
            mutate(month = case_when(
                month == "01" ~ "jan",
                month == "02" ~ "feb",
                month == "03" ~ "mar",
                month == "04" ~ "apr",
                month == "05" ~ "may",
                month == "06" ~ "jun",
                month == "07" ~ "jul",
                month == "08" ~ "aug",
                month == "09" ~ "sep",
                month == "10" ~ "oct",
                month == "11" ~ "nov",
                month == "12" ~ "dec",
                TRUE~ "ERROR"
            )) %>%
            unite("month_year", c(month, year), sep = "_")  
        
        to_date <- parse_character(to_date$month_year)
        
        
        data %>%
            dplyr::select(employee, education, fte_max_capacity, project,
                          from_date():to_date)
        
    })
    
    output$resource_table <- renderDT({
        select_values()
    })
    
}
shinyApp(ui = ui, server = server)


当 from_date 嵌入到 select_values() 的反应式中时,这里的代码可以完美运行。

library(shiny)
library(plotly)
library(shinyjs)
library(shinydashboard)
library(shinyWidgets) 
library(dplyr)
library(tidyr)
library(htmltools)
library(lubridate)
library(DT)
library(janitor)
library(readxl)
library(stringr)



ui = fluidPage(
    useShinyjs(),
    useShinydashboard(),
    tabsetPanel(
        tabPanel("Resource View", fluid = TRUE,
                 sidebarLayout(
                     sidebarPanel(
                         div(id = "inputs",
                             dateRangeInput(
                                 inputId = "date_filter",
                                 label = "Filter by Month and Year",
                                 start = today(),
                                 end = (today() + 90),
                                 min = "Apr-2021",
                                 max = NULL,
                                 format = "M-yyyy",
                                 startview = "month",
                                 weekstart = 0,
                                 language = "en",
                                 separator = " to ",
                                 width = NULL,
                                 autoclose = TRUE
                             ),
                             br()),
                     ),
                     mainPanel(
                         DT::DTOutput("resource_table"),

                     )
                 )
        )
        )
    )
server = function(input, output, session) {
    
    
    
    select_values <- reactive({
        data <- tibble(employee = c("Justin", "Corey","Sibley", "Justin", "Corey","Sibley", "Lisa", "NA"),
                       education = c("graudate", "student", "student", "graudate", "student", "student", "nurse", "doctor"),
                       fte_max_capacity = c(1, 2, 3, 1, 2, 3, 4, 5),
                       project = c("big", "medium", "small", "medium", "small", "small", "medium", "medium"),
                       aug_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       sep_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       oct_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       nov_2021 = c(1, 1, 1, 1, 1, 1, 2, 5))
        

        from_date <- tibble(date = as.character(input$date_filter[1]))
            
            
            from_date <- from_date %>%
                mutate(date = str_remove_all(date, "-..$")) %>%
                separate(date, into = c("year", "month"), sep = "-") %>%
                mutate(month = case_when(
                    month == "01" ~ "jan",
                    month == "02" ~ "feb",
                    month == "03" ~ "mar",
                    month == "04" ~ "apr",
                    month == "05" ~ "may",
                    month == "06" ~ "jun",
                    month == "07" ~ "jul",
                    month == "08" ~ "aug",
                    month == "09" ~ "sep",
                    month == "10" ~ "oct",
                    month == "11" ~ "nov",
                    month == "12" ~ "dec",
                    TRUE~ "ERROR"
                )) %>%
                unite("month_year", c(month, year), sep = "_")
            
            from_date <- parse_character(from_date$month_year)
        
        
        to_date <- tibble(date = as.character(input$date_filter[2]))
        
        to_date <- to_date %>%
            mutate(date = str_remove_all(date, "-..$")) %>%
            separate(date, into = c("year", "month"), sep = "-") %>%
            mutate(month = case_when(
                month == "01" ~ "jan",
                month == "02" ~ "feb",
                month == "03" ~ "mar",
                month == "04" ~ "apr",
                month == "05" ~ "may",
                month == "06" ~ "jun",
                month == "07" ~ "jul",
                month == "08" ~ "aug",
                month == "09" ~ "sep",
                month == "10" ~ "oct",
                month == "11" ~ "nov",
                month == "12" ~ "dec",
                TRUE~ "ERROR"
            )) %>%
            unite("month_year", c(month, year), sep = "_")  
        
        to_date <- parse_character(to_date$month_year)
        
        
        data %>%
            dplyr::select(employee, education, fte_max_capacity, project,
                          from_date:to_date)
        
    })
    
    output$resource_table <- renderDT({
        select_values()
    })
    
}
shinyApp(ui = ui, server = server)

在回答中,如果您还可以解释为什么您的解决方案有效以及我最初的尝试失败的原因,我将不胜感激。谢谢!

编辑:尝试使用变量名来阐明 from_date,但应用程序仍然崩溃

    from_date <- reactiveVal({
        
        start_date <- tibble(date = as.character(input$date_filter[1]))
        
        
        date1 <- start_date %>%
            mutate(date = str_remove_all(date, "-..$")) %>%
            separate(date, into = c("year", "month"), sep = "-") %>%
            mutate(month = case_when(
                month == "01" ~ "jan",
                month == "02" ~ "feb",
                month == "03" ~ "mar",
                month == "04" ~ "apr",
                month == "05" ~ "may",
                month == "06" ~ "jun",
                month == "07" ~ "jul",
                month == "08" ~ "aug",
                month == "09" ~ "sep",
                month == "10" ~ "oct",
                month == "11" ~ "nov",
                month == "12" ~ "dec",
                TRUE~ "ERROR"
            )) %>%
            unite("month_year", c(month, year), sep = "_")
        
        date1 <- parse_character(date1$month_year)
    })
    

知道了!因此,根据@MrFlick 的评论,R 因试图在一个反应​​式中做这么多事情而感到困惑。当我将这 3 个部分中的每一个分成它自己的反应时,我能够让它工作。如果有人知道到达相同终点的更紧凑的方法,很高兴查看其他选项:

library(shiny)
library(dplyr)
library(tidyr)
library(htmltools)
library(lubridate)
library(DT)
library(stringr)



ui = fluidPage(
    useShinyjs(),
    useShinydashboard(),
    tabsetPanel(
        tabPanel("Resource View", fluid = TRUE,
                 sidebarLayout(
                     sidebarPanel(
                         div(id = "inputs",
                             dateRangeInput(
                                 inputId = "date_filter",
                                 label = "Filter by Month and Year",
                                 start = today(),
                                 end = (today() + 90),
                                 min = "Apr-2021",
                                 max = NULL,
                                 format = "M-yyyy",
                                 startview = "month",
                                 weekstart = 0,
                                 language = "en",
                                 separator = " to ",
                                 width = NULL,
                                 autoclose = TRUE
                             ),
                             br()),
                     ),
                     mainPanel(
                         DT::DTOutput("resource_table"),
                         
                     )
                 )
        )
    )
)
server = function(input, output, session) {
    
    from_date_unclean <- reactive({
        
        tibble(date = as.character(input$date_filter[1])) 
        })
        
    from_date_midway <- reactive({
        from_date_unclean() %>%
            mutate(date = str_remove_all(date, "-..$")) %>%
            separate(date, into = c("year", "month"), sep = "-") %>%
            mutate(month = case_when(
                month == "01" ~ "jan",
                month == "02" ~ "feb",
                month == "03" ~ "mar",
                month == "04" ~ "apr",
                month == "05" ~ "may",
                month == "06" ~ "jun",
                month == "07" ~ "jul",
                month == "08" ~ "aug",
                month == "09" ~ "sep",
                month == "10" ~ "oct",
                month == "11" ~ "nov",
                month == "12" ~ "dec",
                TRUE~ "ERROR"
            )) %>%
            unite("month_year", c(month, year), sep = "_")
    })
        
    from_date <- reactive({
        parse_character(from_date_midway()$month_year)
    })
    
    
    to_date_unclean <- reactive({
        tibble(date = as.character(input$date_filter[2]))
    })
    
    to_date_midway <- reactive({
        to_date_unclean() %>%
        mutate(date = str_remove_all(date, "-..$")) %>%
        separate(date, into = c("year", "month"), sep = "-") %>%
        mutate(month = case_when(
            month == "01" ~ "jan",
            month == "02" ~ "feb",
            month == "03" ~ "mar",
            month == "04" ~ "apr",
            month == "05" ~ "may",
            month == "06" ~ "jun",
            month == "07" ~ "jul",
            month == "08" ~ "aug",
            month == "09" ~ "sep",
            month == "10" ~ "oct",
            month == "11" ~ "nov",
            month == "12" ~ "dec",
            TRUE~ "ERROR"
        )) %>%
        unite("month_year", c(month, year), sep = "_") 
    })
    
    to_date <- reactive({
        parse_character(to_date_midway()$month_year)
    })
        


    
    select_values <- reactive({
        data <- tibble(employee = c("Justin", "Corey","Sibley", "Justin", "Corey","Sibley", "Lisa", "NA"),
                       education = c("graudate", "student", "student", "graudate", "student", "student", "nurse", "doctor"),
                       fte_max_capacity = c(1, 2, 3, 1, 2, 3, 4, 5),
                       project = c("big", "medium", "small", "medium", "small", "small", "medium", "medium"),
                       aug_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       sep_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       oct_2021 = c(1, 1, 1, 1, 1, 1, 2, 5),
                       nov_2021 = c(1, 1, 1, 1, 1, 1, 2, 5))
        
        
        
        

        
        
        data %>%
            dplyr::select(employee, education, fte_max_capacity, project,
                          from_date():to_date())
        
    })
    
    output$resource_table <- renderDT({
        select_values()
    })
    
}
shinyApp(ui = ui, server = server)

你应该能够 from_date 一次反应。

  from_date <- reactive({
    fdate1 <- tibble(date = as.character(input$date_filter[1])) 
    fdate2 <- fdate1 %>%
      mutate(date = str_remove_all(date, "-..$")) %>%
      separate(date, into = c("year", "month"), sep = "-") %>%
      mutate(month = case_when(
        month == "01" ~ "jan",
        month == "02" ~ "feb",
        month == "03" ~ "mar",
        month == "04" ~ "apr",
        month == "05" ~ "may",
        month == "06" ~ "jun",
        month == "07" ~ "jul",
        month == "08" ~ "aug",
        month == "09" ~ "sep",
        month == "10" ~ "oct",
        month == "11" ~ "nov",
        month == "12" ~ "dec",
        TRUE~ "ERROR"
      )) %>%
      unite("month_year", c(month, year), sep = "_")
    fdate <- parse_character(fdate2$month_year)
    fdate
  })

to_date也是如此。