生成反应式表格,在闪亮的情况下使用InsertUI和RemoveUI时更新输入

时间:2019-08-21 09:49:28

标签: r shiny shiny-reactivity

我正在构建一个需要添加输入面板并进行输入的应用程序。这些条目应将自己显示在反应表中。添加的面板及其条目也可以删除。因此,根据添加和删除面板后,反应式表格应会扩展或缩回。

所有这些最终都保存为R形式。

我的反应式表仅从一组面板(最近的一组)中获取值,因此制作了一个行表。另外,更新输入不起作用,这导致应用程序崩溃(因此在代码中已注释掉)。

如何处理InsertUI的输入ID以生成反应式表并更新输入?

是否有直接的JS函数可用于通过使用输入ID进行类似的操作?

我为您提供了从三个面板中进行选择的简单代码(单击“添加”后作为一组面板添加)。 “更新”按钮将条目保存为R形式。

   library(shiny)
   library(tidyverse)

       Year <- data.frame(Year =c(seq(1960,2050)))

       #  FUNCTIONS(For Saving and Loading data) 

         Save <- function(data){
            if (exists("response")) {
               response  <<- rbind(response, data)
               response$Row_Num <<- as.numeric(1:nrow(response))
               response <<- response[order(response$Row_Num,decreasing = 
               TRUE),]
               response <<- response[!duplicated(response$ID),]
               response <<- select(response,-c("Row_Num"))
               return(response)
            }
       else {
            response <<- data
         }
        }

      Load <- function() {
           if (exists("response")) {
           response
          }
        }

      # UI Logic

       ui<- fluidPage( 

            fluidRow(h4("Overwrite and Append"),
                     column(4,
                            div(id = "sc", textInput("Scenario","Scenario 
                            Key"))),  
                     column(4,
                            uiOutput("Landuse_Scenario_UI")),
                     column(4,
                            actionButton("Landuse_Update_BUT","Update"))),
            fluidRow( 

              div(id = "Panels",
                  actionButton("Landuse_Add","Add")),
              DT::dataTableOutput("table")))


        # SERVER LOGIC

    server<- function(input,output,session){

        # Reactive values for no of elements inserted or deleted

         vals <- reactiveValues(btn = 0)

        # Add Panels

         observeEvent(input$Landuse_Add, ignoreNULL = FALSE,{
           vals$btn <- vals$btn +1

        insertUI(
        selector = "#Panels",
            ui = splitLayout(id = paste0("Selection",vals$btn ),
                   cellWidths = rep("9.09%",11),
                   cellArgs = list(style = "padding:8px;margin-top:30px"),

                   selectInput(paste("Landuse_Year",vals$btn +1, sep = 
                   ""),"Year",c("",Year$Year), selected = ""),

                   numericInput(paste("Landuse_Crop",vals$btn +1, sep = 
                   ""),"CROP",min= 0, max= 50000,value = "", step = 0.1),

                   numericInput(paste("Landuse_Fallow",vals$btn +1, sep = 
                   ""),"FALLOW",min= 0,max= 50000, value = "",step = 0.1),

                   actionButton(paste0("Landuse_Delete",vals$btn), 
                   "Delete")))


        # Remove Panels alongwith their entries

        observeEvent(input[[paste0("Landuse_Delete",vals$btn)]], {
           shiny::removeUI(selector = paste0("#Selection",vals$btn ))
           vals$btn <- vals$btn - 1    
        })
     })

        # FORM Fillup using the Added Panels

         Landuse_Form <- reactive({  
                if(vals$btn>0){
                  for(i in 1:vals$btn){
             DF0 <- data.frame(Scenario_Key = input$Landuse_Scenario,
                               Year = c(input[["Landuse_Year"]], 
                               input[[paste0("Landuse_Year", i +1)]]),
                               Area_Crop = c(input[["Landuse_Crop"]], 
                               input[[paste0("Landuse_Crop", i +1)]]),
                               Area_Fallow = c(input[["Landuse_Fallow"]], 
                               input[[paste0("Landuse_Fallow", i +1)]]))                     
                               }
                               print(DF0)
                             }
             DF1 <- DF0%>%
                     mutate(ID = paste(Scenario_Key, Year, sep = "-"))%>%
                     drop_na()
             DF1    
                })

          # Creating a Null dataframe using reactive values.

          Landuse_Values <- reactiveValues(DF = data.frame(Scenario_Key = 
                                               character(),
                                               Year = double(),
                                               Area_Crop = double(),
                                               Area_Fallow = double(),
                                               stringsAsFactors = FALSE))

        # Save the Form data

         observeEvent(input$Landuse_Update_BUT, {
         Save(Landuse_Form())

         })

        # LOADING THE FORM 

        Load_Table <- reactive({
        input$Landuse_Update_BUT
        Load()   
        })

       # TABLE TO BE USED FOR SELECTION

        Landuse_Select <- reactive({
        DF0 <- Load_Table ()
             if (exists("DF0")){
                DF0 <- rbind(Landuse_Values$DF,DF0)
              }
              else {
                  Landuse_Values$DF
              }
          })

       # Rendering UI element

         output$Landuse_Scenario_UI<- renderUI({
              selectInput("Landuse_Scenario", "", c(input$Scenario, 
              as.character(Landuse_Select()$Scenario_Key)),selectize = 
              TRUE))  
             })    

       #  UPDATING INPUTS

         #observeEvent(input$Landuse_Scenario,
         # updateNumericInput(session,paste("Landuse_Year",vals$btn +1, 
             sep = ""), "FALLOW", min= 0, max= 50000, min = 1960,max = 
             2050, value = Landuse_Select()$Year     
                           [as.character(Landuse_Select()$Scenario_Key)== 
                           input$Landuse_Scenario], step = 1))

        #observeEvent(input$Landuse_Year,
        #  updateNumericInput(session,paste("Landuse_Crop",vals$btn +1, 
                       sep = ""),"CROP",min= 0, max= 50000,value = 
                      as.numeric(as.character(Landuse_Select()$Area_Crop)) 
                      [Landuse_Select()$Year == input$Landuse_Year & 
                      as.character(Landuse_Select()$Scenario_Key)== 
                      input$Landuse_Scenario] ,step = 0.1))

       #observeEvent(input$Landuse_Year,
       #updateNumericInput(session,paste("Landuse_Fallow",vals$btn +1, sep 
                          = ""), "FALLOW", min= 0, max= 50000,value = 
                     Landuse_Select()$Area_Fallow[Landuse_Select()$Year == 
                     input$Landuse_Year & 
                     as.character(Landuse_Select()$Scenario_Key)== 
                     input$Landuse_Scenario],step = 0.1))


       # RENDERING TABLE

          output$table <- DT::renderDataTable(rownames = FALSE,options = 
           list(sDom  = '<"top">t<"bottom">p'),{

        Landuse_Form()
       })

     }

      shinyApp(ui,server)

代码中产生的错误如下

由于Scenario_Key已经是Landuse_Values $ DF中的变量,因此无法思考为什么会发生此错误。

        Error in paste: object 'Scenario_Key' not found


    Warning: Error in data.frame: arguments imply differing number of rows: 1, 0
         [No stack trace available]

尝试使用updateNumeric输入运行代码时出现消息

   Warning: Error in updateNumericInput: formal argument "min" matched by 
   multiple actual arguments

0 个答案:

没有答案