【问题标题】:How to convert date range input into string in R Shiny?如何将日期范围输入转换为 R Shiny 中的字符串?
【发布时间】:2021-09-11 04:17:41
【问题描述】:

我有一个闪亮的应用程序,当用户选择 Jan 1 和 Q2 如果用户选择 Apr 1 等时,我想在其中创建一个标题为“Q1”,但由于某种原因,我无法转换日期范围输入变成一个字符。

例如,我知道这段代码适用于常规字符串:

 date <- "2020-10-01"
 
library(stringr)
libary(dplyr)
  date <- date %>%
   str_remove("^..") %>%
   str_replace_all("-", "/")
 
 starting <- if(str_detect(date, "../01/01")) {
   print("Q1")
 } else if(str_detect(date, "../04/01")){
   print("Q2")
 } else if(str_detect(date, "../07/01")){
   print("Q3")
 } else if(str_detect(date, "../10/01")){
   print("Q4")
 } else{
   paste0(str_extract(date, ".....$"), "/", str_extract(date, "^.."))
 }
 #Correctly says Q4
 starting

但是,当我尝试将其放入闪亮的应用程序时,我会收到各种错误,例如:

Warning: Error in cat: argument 1 (type 'closure') cannot be handled by 'cat'

如何让这个应用程序使用上面的代码来更改下面消息输出中呈现的文本?注意:为简单起见,我只使用日期过滤器中的第一个输入,但如果由于某种原因,第二个会有所不同,请告诉我我需要做什么。

library(shiny)
library(dplyr)
library(stringr)

ui <- fluidRow(
    column(12,
           div(id = "inputs",
               dateRangeInput(
                   inputId = "date_filter",
                   label = "Filter by Date",
                   start = "2020-01-01",
                   end = (today() + 90),
                   min = "2021-01-01",
                   max = NULL,
                   format = "yyyy-m-d",
                   startview = "month",
                   weekstart = 0,
                   language = "en",
                   separator = " to ",
                   width = NULL,
                   autoclose = TRUE
               )),
        textOutput("message")
    )
)

server <- function(input, output) {
    
    start_date <- reactive({input$datefilter[1]
        })
    
    start_date <- reactive({start_date %>%
        str_remove("^..") %>%
        str_replace_all("-", "/")
    })
    
    starting <- reactive({
        if(str_detect(start_date, "..../01/01")) {
            print("Q1")
        } else if(str_detect(start_date, "..../04/01")){
            print("Q2")
        } else if(str_detect(start_date, "..../07/01")){
            print("Q3")
        } else if(str_detect(start_date, "..../10/01")){
            print("Q4")
        } else{
            paste0(str_extract(start_date, ".....$"), "/", str_extract(start_date, "^.."))
        }
        })
    
    
    output$message <- renderText({
        starting
    })

}

shinyApp(ui = ui, server = server)

编辑:

我也尝试将所有内容放在一个响应式中,但现在我得到一个长度为零的 agument:

    output$message <- renderText({
        
        start_date <- input$datefilter[1]
        
        start_date <- start_date %>%
                str_remove("^..") %>%
                str_replace_all("-", "/")
        
        starting <- 
            if(str_detect(start_date, "..../01/01")) {
                print("Q1")
            } else if(str_detect(start_date, "..../04/01")){
                print("Q2")
            } else if(str_detect(start_date, "..../07/01")){
                print("Q3")
            } else if(str_detect(start_date, "..../10/01")){
                print("Q4")
            } else{
                paste0(str_extract(start_date, ".....$"), "/", str_extract(start_date, "^.."))
            }
    })

【问题讨论】:

  • 不清楚你为什么要使用if/else if..尝试使用format(zoo::as.yearqtr(as.Date(date)), 'Q%q')# [1] "Q4"
  • @akrun,感谢分享功能,我去看看。 if/else 不是问题; Shiny 不允许我将 daterange 输入放入字符串中进行任何一种转换。
  • 以下解决方案对我有用。当用户更改输入时,它会打印季度值

标签: r string date shiny reactive-programming


【解决方案1】:

可以用as.yearqtr 简化,从zoo 转换为yearqtr,然后用format 只提取四分之一

server <- function(input, output) {
  
  
  
  
  output$message <- renderText({
    
    format(zoo::as.yearqtr(input$date_filter[1]), 'Q%q')
  })
  
}

shinyApp(ui = ui, server = server)

-输出


关于 OP 的代码,有几个问题

  1. datefilter 而不是 date_filter
  2. 当我们调用反应式的输出时,使用()。在下面的代码中,它被删除为单个反应式
  3. 在我们得到带有str_remove 的子字符串后,使用.... 作为模式将不匹配。应该是..
server <- function(input, output) {
  
  
  
 
  
  output$message <- renderText({
    
   req(input$date_filter[1])
    tmp <- as.character(input$date_filter[1]) %>%
      str_remove("^..") %>%
      str_replace_all("-", "/")
    
     if(str_detect(tmp, "../01/01")) {
       "Q1"
     } else if(str_detect(tmp, "../04/01")){
       "Q2"
     } else if(str_detect(tmp, "../07/01")){
       "Q3"
     } else if(str_detect(tmp, "../10/01")){
       "Q4"
     } else{
       paste0(str_extract(tmp, ".....$"), "/", str_extract(tmp, "^.."))
     }
     
  })
  
}

-输出

【讨论】:

  • 我很欣赏代码,但不幸的是,我需要使用嵌套的 if/else 语句,因为如果日期正好从 1 月 1 日开始,它应该只显示 Q1,等等。只有当开始日期不t 落在这 4 天之一,那么它必须以我指定的特定格式显示它的实际日期。我尝试在 if/else 语句中修改您的代码,但日期范围不包含前导 0,因此它永远不会匹配。我还需要将此信息作为我导出的 powerpoint 表的字符串,因此不仅仅是渲染它。你有什么建议吗?
  • @J.Sabree 您在帖子中显示的代码,在 shiiny 之外给了我starting# [1] "10/01 '20"。这是你的预期吗
  • 好收获。我现在修复了代码。如果从 10 月 1 日等开始,则应显示第 4 季度,如果不是在 4 个季度中的一个开始(如 2020 年 11 月 1 日),则应显示 20 年 1 月 1 日。
  • @J.Sabree 我理解这个问题。有多个问题 - datefilter 不是 date_filter 并且您需要在调用时使用 ()
  • 哇,我觉得我错过了炒作很傻。您的解决方案有效,但只有一个标注:在最后,当我通过 renderText 传递它时,我不必使用 ()。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-12-10
  • 2018-03-30
  • 2017-06-11
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2012-05-29
相关资源
最近更新 更多