【问题标题】:Adjust shiny code to generate the results as in the first code调整闪亮的代码以生成第一个代码中的结果
【发布时间】:2021-10-16 09:08:49
【问题描述】:

你能帮我调整下面的第二个代码吗?第一个代码正常工作。首先,我使用了一个名为Test 的数据库,它完全符合我的要求。在第二个代码中注意我有一个df1 数据库,一个函数然后它生成一个Test 数据库。第二个代码的Test 数据库生成的结果与第一个代码的Test 数据库完全相同,不同之处在于在第一个中我指定了 Test 的值,而在另一个中我使用了生成的函数。但是,在第二个代码中,当我运行闪亮时它不会显示结果,就像在第一个代码中一样,我想对其进行调整。

第一个代码

library(shiny)
library(shinythemes)
library(dplyr)
library(writexl)
library(tidyverse)
library(lubridate)

Test <- structure(list(date2 = structure(c(18808, 18808, 18809, 18810
), class = "Date"), Category = c("FDE", "ABC", "FDE", "ABC"), 
    coef = c(4, 1, 6, 1)), row.names = c(NA, 4L), class = "data.frame")

ui <- fluidPage(
  
  shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
                          br(),
                          tabPanel("",
                                   sidebarLayout(
                                     sidebarPanel(
                                       uiOutput('daterange'),
                                       br()
                                       
                                     ),
                                     mainPanel(
                                         dataTableOutput('table'),
                                         br(), br(), 
                                         downloadButton("dl", "Download")
                                     ),
                                   ))
  ))

server <- function(input, output,session) {
  
  data <- reactive(Test)
  
  data_subset <- reactive({
    req(input$daterange1)
    days <- seq(input$daterange1[1], input$daterange1[2], by = 'day')
    subset(data(), date2 %in% days)
  })
  
  output$daterange <- renderUI({
    dateRangeInput("daterange1", "Period you want to see:",
                   start = min(data()$date2),
                   end   = max(data()$date2))
  })
  
  output$table <- renderDataTable({
    data_subset()
  })
  
  output$dl <- downloadHandler(
    filename = function() { "data.xlsx"},
    content = function(file) {
      writexl::write_xlsx(data_subset(), path = file)
      }
  )
}

shinyApp(ui = ui, server = server)

第二个代码

library(shiny)
library(shinythemes)
library(dplyr)
library(writexl)
library(tidyverse)
library(lubridate)

function.test<-function(){
  
  df1 <- structure(
    list(date1= c("2021-06-28","2021-06-28","2021-06-28","2021-06-28"),
         date2 = c("2021-06-30","2021-06-30","2021-07-01","2021-07-02"),
         Category = c("FDE","ABC","FDE","ABC"),
         Week= c("Wednesday","Wednesday","Friday","Friday"),
         DR1 = c(4,1,6,1),
         DR01 = c(4,1,4,4), DR02= c(4,2,6,0),DR03= c(9,5,4,0),
         DR04 = c(5,4,3,5),DR05 = c(5,4,5,0),
         DR06 = c(2,4,3,5),DR07 = c(2,5,4,0),
         DR08 = c(3,4,5,0),DR09 = c(2,3,4,0)),
    class = "data.frame", row.names = c(NA, -4L))
  
return(df1)
  
  }
  
  return_coef <- function(df1, dmda, CategoryChosse) {
    
    x<-df1 %>% select(starts_with("DR0"))
    
    x<-cbind(df1, setNames(df1$DR1 - x, paste0(names(x), "_PV")))
    PV<-select(x, date2,Week, Category, DR1, ends_with("PV"))
    
    med<-PV %>%
      group_by(Category,Week) %>%
      summarize(across(ends_with("PV"), median))
    
    SPV<-df1%>%
      inner_join(med, by = c('Category', 'Week')) %>%
      mutate(across(matches("^DR0\\d+$"), ~.x + 
                      get(paste0(cur_column(), '_PV')),
                    .names = '{col}_{col}_PV')) %>%
      select(date1:Category, DR01_DR01_PV:last_col())
    
    SPV<-data.frame(SPV)
    
    mat1 <- df1 %>%
      filter(date2 == dmda, Category == CategoryChosse) %>%
      select(starts_with("DR0")) %>%
      pivot_longer(cols = everything()) %>%
      arrange(desc(row_number())) %>%
      mutate(cs = cumsum(value)) %>%
      filter(cs == 0) %>%
      pull(name)
    
    (dropnames <- paste0(mat1,"_",mat1, "_PV"))
    
    SPV <- SPV %>%
      filter(date2 == dmda, Category == CategoryChosse) %>%
      select(-any_of(dropnames))
    
    datas<-SPV %>%
      filter(date2 == ymd(dmda)) %>%
      group_by(Category) %>%
      summarize(across(starts_with("DR0"), sum)) %>%
      pivot_longer(cols= -Category, names_pattern = "DR0(.+)", values_to = "val") %>%
      mutate(name = readr::parse_number(name))
    colnames(datas)[-1]<-c("Days","Numbers")
    
    datas <- datas %>% 
      group_by(Category) %>% 
      slice((as.Date(dmda) - min(as.Date(df1$date1) [
        df1$Category == first(Category)])):max(Days)+1) %>%
      ungroup
    
    mod <- nls(Numbers ~ b1*Days^2+b2,start = list(b1 = 0,b2 = 0),data = datas, algorithm = "port")
    as.numeric(coef(mod)[2])
    
    Test<-cbind(df1 %>% select(date2,Category), coef = mapply(return_coef, df1$date2, df1$Category))

}

ui <- fluidPage(
  
  shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
                    br(),
                    tabPanel("",
                             sidebarLayout(
                               sidebarPanel(
                                 uiOutput('daterange'),
                                 br()
                                 
                               ),
                               mainPanel(
                                 dataTableOutput('table'),
                                 br(), br(), 
                                 downloadButton("dl", "Download")
                               ),
                             ))
  ))

server <- function(input, output,session) {
  
  data <- reactive(function.test())
  
  data_subset <- reactive({
    req(input$daterange1)
    days <- seq(input$daterange1[1], input$daterange1[2], by = 'day')
    subset(data(), date2 %in% days)
  })
  
  output$daterange <- renderUI({
    dateRangeInput("daterange1", "Period you want to see:",
                   start = min(data()$date2),
                   end   = max(data()$date2))
  })
  
  output$table <- renderDataTable({
    data_subset()
  })
  
  output$dl <- downloadHandler(
    filename = function() { "data.xlsx"},
    content = function(file) {
      writexl::write_xlsx(data_subset(), path = file)
    }
  )
}

shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    在你的函数中,你正在调用它自己。此外,它永远不会在服务器端使用。因此,您将获得子集数据中的所有变量。试试这个

    library(shiny)
    library(shinythemes)
    library(dplyr)
    library(writexl)
    library(tidyverse)
    library(lubridate)
    
    function.test<-function(){
    
      df1 <- structure(
        list(date1= c("2021-06-28","2021-06-28","2021-06-28","2021-06-28"),
             date2 = c("2021-06-30","2021-06-30","2021-07-01","2021-07-02"),
             Category = c("FDE","ABC","FDE","ABC"),
             Week= c("Wednesday","Wednesday","Friday","Friday"),
             DR1 = c(4,1,6,1),
             DR01 = c(4,1,4,4), DR02= c(4,2,6,0),DR03= c(9,5,4,0),
             DR04 = c(5,4,3,5),DR05 = c(5,4,5,0),
             DR06 = c(2,4,3,5),DR07 = c(2,5,4,0),
             DR08 = c(3,4,5,0),DR09 = c(2,3,4,0)),
        class = "data.frame", row.names = c(NA, -4L))
    
      return(df1)
    
    }
    
    return_coef <- function(df1, dmda, CategoryChosse) {
    
      x<-df1 %>% select(starts_with("DR0"))
    
      x<-cbind(df1, setNames(df1$DR1 - x, paste0(names(x), "_PV")))
      PV<-select(x, date2,Week, Category, DR1, ends_with("PV"))
    
      med<-PV %>%
        group_by(Category,Week) %>%
        summarize(across(ends_with("PV"), median))
    
      SPV<-df1%>%
        inner_join(med, by = c('Category', 'Week')) %>%
        mutate(across(matches("^DR0\\d+$"), ~.x +
                        get(paste0(cur_column(), '_PV')),
                      .names = '{col}_{col}_PV')) %>%
        select(date1:Category, DR01_DR01_PV:last_col())
    
      SPV<-data.frame(SPV)
    
      mat1 <- df1 %>%
        filter(date2 == dmda, Category == CategoryChosse) %>%
        select(starts_with("DR0")) %>%
        pivot_longer(cols = everything()) %>%
        arrange(desc(row_number())) %>%
        mutate(cs = cumsum(value)) %>%
        filter(cs == 0) %>%
        pull(name)
    
      (dropnames <- paste0(mat1,"_",mat1, "_PV"))
    
      SPV <- SPV %>%
        filter(date2 == dmda, Category == CategoryChosse) %>%
        select(-any_of(dropnames))
    
      datas<-SPV %>%
        filter(date2 == ymd(dmda)) %>%
        group_by(Category) %>%
        summarize(across(starts_with("DR0"), sum)) %>%
        pivot_longer(cols= -Category, names_pattern = "DR0(.+)", values_to = "val") %>%
        mutate(name = readr::parse_number(name))
      colnames(datas)[-1]<-c("Days","Numbers")
    
      datas <- datas %>%
        group_by(Category) %>%
        slice((as.Date(dmda) - min(as.Date(df1$date1) [
          df1$Category == first(Category)])):max(Days)+1) %>%
        ungroup
    
      mod <- nls(Numbers ~ b1*Days^2+b2,start = list(b1 = 0,b2 = 0),data = datas, algorithm = "port")
      return(round(as.numeric(coef(mod)[2])))
    
      # Test<-cbind(df1 %>% select(date2,Category), coef = mapply(return_coef, df1$date2, df1$Category))
    
    }
    
    ui <- fluidPage(
    
      shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
                        br(),
                        tabPanel("",
                                 sidebarLayout(
                                   sidebarPanel(
                                     uiOutput('daterange'),
                                     br()
    
                                   ),
                                   mainPanel(
                                     dataTableOutput('table'),
                                     br(), br(),
                                     downloadButton("dl", "Download")
                                   ),
                                 ))
      ))
    
    server <- function(input, output,session) {
    
      data <- reactive(function.test())
    
      data_subset <- reactive({
        req(input$daterange1)
        days <- seq(input$daterange1[1], input$daterange1[2], by = 'day')
        df1 <- subset(data(), as.Date(date2) %in% days)
        df2 <- df1 %>% select(date2,Category)
        Test <- cbind(df2, coef = apply(df2, 1, function(x) {return_coef(df1,x[1],x[2])}))
        Test
      })
    
      output$daterange <- renderUI({
        dateRangeInput("daterange1", "Period you want to see:",
                       start = min(data()$date2),
                       end   = max(data()$date2),
                       min   = min(data()$date2),
                       max   = max(data()$date2)
                      )
      })
    
      output$table <- renderDataTable({
        data_subset()
      })
    
      output$dl <- downloadHandler(
        filename = function() { "data.xlsx"},
        content = function(file) {
          writexl::write_xlsx(data_subset(), path = file)
        }
      )
    }
    
    shinyApp(ui = ui, server = server)
    

    【讨论】:

    • 谢谢 YBS,就是这样。你知道你是否可以在daterange 中禁用不属于我的数据库的日期吗?因为它是这样的,它适用于所有日期
    • 添加最小值和最大值应该对此有所帮助 - 请参阅更新的代码。此外,我没有看到您在最近发布的问题中提到的问题,即当日期范围中的显示周期发生变化时 coeff 值发生变化。
    • 感谢 YBS!关于最近的问题,您是否使用了我放在那里的代码?您看到了我插入的图像,直到 04/07 是正确的值,但是当我将其更改为 03/07 时,系数值发生了变化,对您来说不是吗?
    • 不,我在这个答案中使用了代码。让我试试其他代码。
    • YBS,对此问题的任何建议:stackoverflow.com/questions/69622756/…
    【解决方案2】:

    问题出在您生成的数据中,日期是字符串,而不是日期。如果您将function.test() 定义更改为以下内容,它应该可以工作:

    function.test<-function(){
      
      df1 <- structure(
        list(date1= as.Date(c("2021-06-28","2021-06-28","2021-06-28","2021-06-28"), format="%Y-%m-%d"),
             date2 = as.Date(c("2021-06-30","2021-06-30","2021-07-01","2021-07-02"), format="%Y-%m-%d"),
             Category = c("FDE","ABC","FDE","ABC"),
             Week= c("Wednesday","Wednesday","Friday","Friday"),
             DR1 = c(4,1,6,1),
             DR01 = c(4,1,4,4), DR02= c(4,2,6,0),DR03= c(9,5,4,0),
             DR04 = c(5,4,3,5),DR05 = c(5,4,5,0),
             DR06 = c(2,4,3,5),DR07 = c(2,5,4,0),
             DR08 = c(3,4,5,0),DR09 = c(2,3,4,0)),
        class = "data.frame", row.names = c(NA, -4L))
      
      return(df1)
      
    }
    

    也许您已经知道这一点,所以如果这个附加部分没有帮助,我深表歉意,但我总是发现使用 browse() 函数进入应用程序很有用。如果您在 UI 中添加以下内容:

    actionButton("browser", "browser"),
    

    以及您的server 函数中的以下内容:

      observeEvent(input$browser,{
        browser()
      })
    

    它将创建一个按钮,让您可以查看应用中的反应元素。使用原始公式,您可以查看生成的数据及其属性:

    Browse[1]> data()
    #        date1      date2 Category      Week DR1 DR01 DR02 DR03 DR04 DR05 DR06 DR07 DR08 DR09
    # 1 2021-06-28 2021-06-30      FDE Wednesday   4    4    4    9    5    5    2    2    3    2
    # 2 2021-06-28 2021-06-30      ABC Wednesday   1    1    2    5    4    4    4    5    4    3
    # 3 2021-06-28 2021-07-01      FDE    Friday   6    4    6    4    3    5    3    4    5    4
    # 4 2021-06-28 2021-07-02      ABC    Friday   1    4    0    0    5    0    5    0    0    0
    
    Browse[1]> str(data())
    # 'data.frame': 4 obs. of  14 variables:
    # $ date1   : chr  "2021-06-28" "2021-06-28" "2021-06-28" "2021-06-28"
    # $ date2   : chr  "2021-06-30" "2021-06-30" "2021-07-01" "2021-07-02"
    # $ Category: chr  "FDE" "ABC" "FDE" "ABC"
    # $ Week    : chr  "Wednesday" "Wednesday" "Friday" "Friday"
    # $ DR1     : num  4 1 6 1
    # $ DR01    : num  4 1 4 4
    # $ DR02    : num  4 2 6 0
    # $ DR03    : num  9 5 4 0
    # $ DR04    : num  5 4 3 5
    # $ DR05    : num  5 4 5 0
    # $ DR06    : num  2 4 3 5
    # $ DR07    : num  2 5 4 0
    # $ DR08    : num  3 4 5 0
    # $ DR09    : num  2 3 4 0
    

    这清楚地表明日期变量是字符串。您还可以查看data_subset() 以验证它没有任何数据:

    Browse[1]> data_subset()
    # [1] date1    date2    Category Week     DR1      DR01     DR02     DR03     DR04     DR05     DR06     DR07     DR08     DR09    
    # <0 rows> (or 0-length row.names)
    

    这将允许您进行一些挖掘:

    Browse[1]> days <- seq(input$daterange1[1], input$daterange1[2], by = 'day')
    Browse[1]> days
    # [1] "2021-06-30" "2021-07-01" "2021-07-02"
    Browse[1]> data()$date2 %in% days
    # [1] FALSE FALSE FALSE FALSE
    Browse[1]> class(days)
    # [1] "Date"
    Browse[1]> class(data()$date2)
    # [1] "character"
    

    这使您可以确定date2 变量与days 向量是不同的类,这是问题的症结所在。

    【讨论】:

    • 感谢戴夫的回复。我做了你在df1 中评论的这个调整,它甚至生成了一个闪亮的表,但请注意生成的表与第一个代码不同。第一个代码表只有 date2、category 和 coef 列。代码 2 的表格必须与第一个相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 2015-02-05
    • 1970-01-01
    • 2013-09-12
    相关资源
    最近更新 更多