【问题标题】:Keep multiple changes in a shiny app after updating values更新值后在闪亮的应用程序中保留多项更改
【发布时间】:2019-01-30 03:13:03
【问题描述】:

我有一个闪亮的应用程序,其中有两个表。如您所见,用户使用正确的数据表和那里的小部件,以便在左侧的 rhandsontable 中显示结果。该应用程序按预期工作,除了每次我通过selectInput()“标签”选择不同的测试时,我之前所做的所有更改都会丢失并且左侧的rhandsontable“重新启动”。我使用this 来保留修改后的名称,但我需要对整个应用应用类似的逻辑。

应用逻辑:

用户使用 selectInput()“标签”选择其中一个测试。这是主要操作,然后他可以修改其名称,例如 Test 1 到 Test A。然后用户可以通过 numericInput() "Items in Test" 在 Test 中添加项目。这些是总项目。正如您将看到的,“测试中的项目”的数量与所选测试的 hot3 表中的“可用”列相同。通过“选择项目”,他可以选择要在 hot5 表中显示的特定项目。然后用户可以点击 hot5 表来选择一个特定的项目,选择项目(或行)的数量会显示在 hot3 表中的“Sel”列下,用于这个特定的测试。 “选择的项目”仅显示在“选择项目”中选择的项目数量。请注意,发生在表上的每次修改都不依赖于其他小部件。这意味着例如不需要更改标签名称。

library(shiny)
library(DT)
library(rhandsontable)
library(tidyverse)

ui <- navbarPage(
  "Application",
  tabPanel("Booklets",
           sidebarLayout(
             sidebarPanel(
               uiOutput("tex2"),
               rHandsontableOutput("hot3")
             ),
             mainPanel(
               fluidRow(
                 wellPanel(
                   fluidRow(
                     column(4,
                            DT::dataTableOutput("hot5")       
                     ),
                     column(4,
                            fluidRow(
                              uiOutput("book3"),
                              uiOutput("book6")

                            ),
                            fluidRow(
                              uiOutput("book1"),
                              uiOutput("book10"),
                              uiOutput("book11")
                            )
                     )
                   ))
               )
             )
           )
  )
  )
#server
server <- function(input, output, session) {

  output$tex2<-renderUI({
    numericInput("text2", "#tests", value = 1, min=1)
  })

  output$book1<-renderUI({
    numericInput("bk1", 
                 "Items in test", 
                 value = 1,
                 min = 1)
  })
  output$book3<-renderUI({

    selectInput("bk3", 
                "Label", 
                choices=(paste("Test",1:input$text2)))
  })


  output$book6<-renderUI({
    textInput("bk6", "Change to",
              value=NULL
    )
  })


  output$book10<-renderUI({
    selectizeInput(
      "bk10", "Select Items", choices =1:10000,multiple =T,selected = 1,
      options = list(maxItems = input$bk1))
  })
  output$book11<-renderUI({
    textInput("bk11", "Items chosen",
              value = nrow(rt5())
    )
  })


  rt4<-reactive({

    if(is.null(input$bk6)|input$bk6==""){
      if(is.null(input$hot5_rows_selected)|| is.na(input$hot5_rows_selected)){
        DF=data.frame(
          Sel. = rep(TRUE, input$text2),
          Test=paste(1:input$text2),
          Label=paste("Test",1:input$text2),
          Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
          Sel =as.integer(rep.int(0,input$text2)),
          stringsAsFactors = FALSE)
      }
      else{
        DF=data.frame(
          Sel. = rep(TRUE, input$text2),
          Test=paste(1:input$text2),
          Label=paste("Test",1:input$text2),
          Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
          Sel =as.integer(rep.int(0,input$text2)),
          stringsAsFactors = FALSE)
      }
      for(i in 1 : input$text2){
        if(DF[i,3]==input$bk3){
          DF[i,4]<-input$bk1
          DF[i,5]<-length(input$hot5_rows_selected)
        }
        else{
          DF[i,4]<-1

        }
      }

      DF
    }
    else{
      if(is.null(input$hot5_rows_selected)|| is.na(input$hot5_rows_selected)){
        DF=data.frame(
          Sel. = rep(TRUE, input$text2),
          Test=paste(1:input$text2),
          Label=paste("Test",1:input$text2),
          Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
          Sel =as.integer(rep.int(0,input$text2)),
          stringsAsFactors = FALSE)
        DF[DF==input$bk3]<-input$bk6
        DF
      }
      else{
        DF=data.frame(
          Sel. = rep(TRUE, input$text2),
          Test=paste(1:input$text2),
          Label=paste("Test",1:input$text2),
          Avail.=format(round(as.integer(rep.int(input$bk1,input$text2))),0),
          Sel =as.integer(rep.int(0,input$text2)),
          stringsAsFactors = FALSE)
        DF[DF==input$bk3]<-input$bk6
        DF
      }

      for(i in 1 : input$text2){
        if(DF[i,3]==input$bk6){
          DF[i,4]<-input$bk1
          DF[i,5]<-length(input$hot5_rows_selected)
        }
        else{
          DF[i,4]<-1

        }
      }
      DF
    }

  })

  rt55<-reactive({
    DF=data.frame(
      Id=  input$bk10,
      Label=paste("Item",input$bk10),
      Pf=0,
      stringsAsFactors = FALSE
    )
  })

  rt5<-reactive({
    DF=data.frame(
      Id=  input$bk10,
      Label=paste("Item",input$bk10),
      Pf=0,
      stringsAsFactors = FALSE
    )
    cbind(id=rowSelected(), DF)
  })

  rowSelected <- reactive({
    x <- numeric(nrow(rt55()))
    x[input$hot5_rows_selected] <- 1
    x
  })

  output$hot5 <- renderDT(datatable(rt5()[,-1],
                                    selection = list(mode = "multiple",
                                                     selected = (1:nrow(rt5()[,-1]))[as.logical(rowSelected())],
                                                     target = "row"),rownames = F)
  )



  output$hot3 <-renderRHandsontable(
    rhandsontable(rt4())

  )



}

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    基于 cmets 进行编辑。我认为代码有效,但它相当脆弱,需要相当程度的错误处理。例如,在提交后重置条目

    library(shiny)
    library(DT)
    library(rhandsontable)
    #library(tidyverse)
    
    ui <- navbarPage(
      "Application",
      tabPanel("Booklets",
               sidebarLayout(
                 sidebarPanel(
                   uiOutput("tex2"),
                   rHandsontableOutput("hot3")
                 ),
                 mainPanel(
                   fluidRow(
                     wellPanel(
                       fluidRow(
                         column(4,
                                DT::dataTableOutput("hot5")
                         ),
                         column(4,
                                fluidRow(
                                  uiOutput("book3"),
                                  uiOutput("book6")
    
                                ),
                                fluidRow(
                                  uiOutput("book1"),
                                  uiOutput("book10"),
                                  uiOutput("book11")
                                ),
                                fluidRow(actionButton("submit","submit"))
                         )
                       ))
                   )
                 )
               )
      )
    )
    #server
    server <- function(input, output, session) {
    
      rv<-reactiveValues()
    
      output$tex2<-renderUI({
        numericInput("text2", "#tests", value = 1, min=1)
      })
    
      output$book1<-renderUI({
        numericInput("bk1",
                     "Items in test",
                     value = 1,
                     min = 1)
      })
    
      output$book3<-renderUI({
    
        selectInput("bk3",
                    "Label",
                    choices=(paste("Test",1:input$text2)))
    
      })
    
    
      output$book6<-renderUI({
        textInput("bk6", "Change to",
                  value=NULL
        )
      })
    
    
      output$book10<-renderUI({
        # changed from selectize
        selectizeInput(
          "bk10", "Select Items", choices =1:10000,multiple =T,selected = 1,
          options = list(maxItems = input$bk1))#changed from
      })
      output$book11<-renderUI({
        textInput("bk11", "Items chosen",
                  value = nrow(rt5())
        )
      })
    
      #rt4<-reactive({
      observe({
        req(input$text2)
    
        rv$rt4 = data.frame(
          SNo = rep(TRUE, input$text2),
          Test=paste(1:input$text2),
          Label=paste("Test",1:input$text2),
          Avail=1L,
          Sel =as.integer(rep.int(0,input$text2)),
          stringsAsFactors = FALSE)
      })
    
      observeEvent(input$submit,{
    
     # rt4 <- reactive({
        if (is.null( rv$rt4))
          return(NULL)
    
        if(!is.null(input$bk6) && input$bk6!=""){
          rv$rt4[ rv$rt4$Label==input$bk3, "Avail"] <- input$bk1
          rv$rt4[ rv$rt4$Label==(input$bk3), "Sel"] <- length(input$hot5_rows_selected)
    
          rv$rt4[ rv$rt4$Label==input$bk3, "Label"] <- input$bk6
        }
        # if(!is.null(input$hot5_rows_selected) && input$hot5_rows_selected!=""){
        #
        # }
      })
    
      observeEvent(input$submit,{
    
        updateSelectInput(session,"bk3","Label", choices=rv$rt4$Label)
      }
      )
    
    
      rt55<-reactive({
        DF=data.frame(
          Id=  input$bk10,
          Label=paste("Item",input$bk10),
          Pf=0,
          stringsAsFactors = FALSE
        )
      })
    
      rt5<-reactive({
        DF=data.frame(
          Id=  input$bk10,
          Label=paste("Item",input$bk10),
          Pf=0,
          stringsAsFactors = FALSE
        )
        cbind(id=rowSelected(), DF)
      })
    
      rowSelected <- reactive({
        x <- numeric(nrow(rt55()))
        x[input$hot5_rows_selected] <- 1
        x
      })
    
      output$hot5 <- renderDT(datatable(rt5()[,-1],
                                        selection = list(mode = "multiple",
                                                         selected = (1:nrow(rt5()[,-1]))[as.logical(rowSelected())],
                                                         target = "row"),rownames = F)
      )
    
      output$hot3 <-renderRHandsontable({
        req(input$text2)
        rhandsontable(rv$rt4)
      })
    }
    shinyApp(ui,server)
    

    【讨论】:

    • 谢谢,但现在所有选定的测试都发生了变化,而不仅仅是 selectInput()“标签”选择的测试。如果您检查我的初始代码,您将完全了解该应用程序的使用方式。问题是它无法保留这些值。
    • 你能再解释一下吗?现在用户有两种方法来改变表 hot3。通过从 bk3 输入中选择他选择的标签,然后将值更改为 bk6 中的输入。或者直接编辑 hot3 rhandontable 中的值。这不是想要的输出吗?
    • 再次感谢您的光临。我编辑了 Q 以提供有关应用程序逻辑的更多详细信息。 hot3 表只能通过 hot5 表和那里的小部件进行修改。
    • 我现在明白其中的逻辑了。引入提交按钮(操作按钮)可以吗?
    • 我更改了一些列名(Avail. 到 Avail,Sel. 到 SNo)。这些变化只是风格和装饰
    猜你喜欢
    • 2019-01-29
    • 1970-01-01
    • 2020-06-24
    • 2019-01-10
    • 2018-03-24
    • 2017-11-18
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多