【问题标题】:Collect All user inputs throughout the Shiny App收集整个 Shiny 应用程序中的所有用户输入
【发布时间】:2017-04-23 05:31:26
【问题描述】:

有没有一种方法可以在 UI 中的其他位置显示来自 textInput() 的值,而不必通过像下面这样非常冗长的内容通过 server.R

ui.R

library(shiny)
shinyUI(
  fluidPage(
  textInput('text_in', label = 'Write text here'),

  # elsewhere in the UI...

  textOutput('text_out')
))

server.R

library(shiny)
shinyServer(function(input, output) {
  output$text_out = renderText(input$text_in)
})

这个例子还不错,但是当我需要做很多次时它变得非常冗长。我的愿望是收集用户在整个应用程序中输入的所有输入,并在最后将它们编译成一个漂亮的表格,这样他们就可以确认所有内容都是正确的。

我看到在 conditionalPanel() 中使用 JavaScript 表达式时,您可以在不通过服务器的情况下引用输入元素,但我不确定如何在此特定实例之外实现它。

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    要访问所有输入,您可以使用reactiveValuesToList server-side。您可以通过 Javascript 事件访问输入值,如下所示(我以@Pork Chop 为例):

    library(shiny)
    
    ui <- basicPage(
    
      fluidRow(
        column(
          width = 6,
          textInput('a', 'Text A',"a1"),
          textInput('b', 'Text B',"b1"),
          textInput('c', 'Text A',"c1"),
          textInput('d', 'Text B',"d1"),
          textInput('e', 'Text A',"e1"),
          textInput('f', 'Text B',"f1")
        ),
        column(
          width = 6,
          tags$p("Text A :", tags$span(id = "valueA", "")),
          tags$script(
            "$(document).on('shiny:inputchanged', function(event) {
              if (event.name === 'a') {
                $('#valueA').text(event.value);
              }
            });
            "
          ),
          tableOutput('show_inputs')
        )
      )
    )
    
    server <- shinyServer(function(input, output, session){
    
      AllInputs <- reactive({
        x <- reactiveValuesToList(input)
        data.frame(
          names = names(x),
          values = unlist(x, use.names = FALSE)
        )
      })
    
      output$show_inputs <- renderTable({
        AllInputs()
      })
    })
    shinyApp(ui = ui, server = server)
    

    【讨论】:

      【解决方案2】:

      由于您的总体目标是收集所有用户输入,然后将它们编译成一个表格,我将通过下面的示例向您展示如何实现这一目标。如您所见,所有input 变量都可以通过server 中的名称访问。我将它们保持在被动状态,以防您需要它进行进一步分析或某些renderUI 功能。

      #rm(list=ls())
      library(shiny)
      
      ui <- basicPage(
        textInput('a', 'Text A',"a1"),
        textInput('b', 'Text B',"b1"),
        textInput('c', 'Text A',"c1"),
        textInput('d', 'Text B',"d1"),
        textInput('e', 'Text A',"e1"),
        textInput('f', 'Text B',"f1"),
        tableOutput('show_inputs')
      )
      server <- shinyServer(function(input, output, session){
      
        AllInputs <- reactive({
          myvalues <- NULL
          for(i in 1:length(names(input))){
            myvalues <- as.data.frame(rbind(myvalues,(cbind(names(input)[i],input[[names(input)[i]]]))))
          }
          names(myvalues) <- c("User Input","Last Value")
          myvalues
        })
      
        output$show_inputs <- renderTable({
          AllInputs()
        })
      })
      shinyApp(ui = ui, server = server)
      

      【讨论】:

        【解决方案3】:

        如果闪亮的输入都具有不同的长度并且上述方法不起作用(例如,如果您有单选按钮、复选框组、文本输入等的组合),这将起作用并且可以生成一个您可以解析的variable:value 表稍后:

        AllInputs <- reactive({
          myvalues <- NULL
          newvalues <- NULL
          for(i in 1:length(names(input))){
            newvalues <- paste(names(input)[i], input[[names(input)[i]]], sep=":")
            myvalues <- append(myvalues, newvalues)
          }
          myvalues
        })
        
        output$show_inputs <- renderTable({
          AllInputs()
        })
        

        【讨论】:

          【解决方案4】:

          借鉴Pork ChopmysteRious,这是一个适用于闪亮中多种类型的文本和数字输入的解决方案。

          library(shiny)
          
          AdvRchp3 <- "While you’ve probably already used many (if not all) 
          of the different types of vectors, you may not have thought 
          deeply about how they’re interrelated. In this chapter, 
          I won’t cover individual vectors types in too much detail, 
          but I will show you how all the types fit together as a whole. 
          If you need more details, you can find them in R’s documentation."
          
          ui <- fluidPage(
            fluidRow(
              h4("Text Inputs"),
              textInput("text_input", "Input some Text", value = "some text"),
              passwordInput("password_input", "Input a Password", value = "1234"),
              textAreaInput("text_area_input", "Input lots of Text", rows = 3, value = AdvRchp3)
            ),
            fluidRow(
              h4("Numeric Inputs"),
              numericInput("numeric_input", "Number 1", value = 1, min = 0, max = 100),
              sliderInput("slider_input_single", "Number 50", value = 50, min = 0, max = 100),
              sliderInput("slider_input_ranges", "Range 10 to 20", value = c(10, 20), min = 0, max = 100)
            ),
            fluidRow(
              tableOutput("show_inputs")
            )
          )  
          
          server <- function(input, output, session) {
            all_inputs <- reactive({
              input_df <- NULL
              df_row <- NULL
              for(i in 1:length(names(input))){
                df_row <- as.data.frame(cbind(names(input)[i], input[[names(input)[i]]]))
                input_df <- as.data.frame(dplyr::bind_rows(input_df, df_row))
              }
              names(input_df) <- c("input_id", "input_val")
              input_df
            })
            
            output$show_inputs <- renderTable({
              all_inputs()
            })
          }
          
          shinyApp(ui, server)
          

          注意:rbind 现在是dplyr::bind_rows,但plyr::rbind.fill 也可以使用。

          【讨论】:

            猜你喜欢
            • 2013-11-25
            • 2021-08-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-03
            • 1970-01-01
            • 2019-11-08
            相关资源
            最近更新 更多