简体   繁体   中英

Using the inputs of a dynamic select box in R Shiny

I want to capture key-value pairs via Shiny (R) where a few widgets (keys) are selected by the user via the UI from a known but large list of possible optionss.

Corresponding to each Widget he selects a numeric input box is shown where he can then enter a value (quantity).

I posted a demo here:

https://statspot.shinyapps.io/app_upload_test/

在此处输入图片说明

For further processing it would be nice to have a data-frame with those key value pairs that were selected / entered by the user. That's the red table below. ie A dataframe with widgets selected & their corresponding quantities entered.

My problem is I haven't figured out how to get the values entered by the user dynamically in there (I've put in 999 as a static filler dummy value for now). The keys I could manage.

ie In the case of the input select above I'd want the following output

data.frame(widgets=c("Widget B","Widget A"),quantities=c(600,400))

Any ideas or pointers?

My code is here:

library(shiny)

widget_list<-c("WidgetA","WidgetB","WidgetC","WidgetD","WidgetE")

ui <- fluidPage(title = "Test Case for Dynamic Inputs",

                headerPanel(h3("Test Case for Dynamic Inputs")),
                sidebarPanel(width = 3,
                             selectInput("widgets","Select Widgets",choices=widget_list,multiple = TRUE)
                ),
                sidebarPanel(title="Scoring Outputs",width = 3,
                             h3(textOutput("title"))
                ),
                sidebarPanel(title="Dynamic  UI",width=3,
                             uiOutput("widget_quantities"),
                             h4(tableOutput("output_table"),style="color: red")

                             )
)

server <- function(input, output) {

  output$title<-renderText("Test dynamic inputs")

  fn_run<-reactive({
    count_widgets(input$widgets)
  })

  len_widgets<-reactive({
    length(input$widgets)
  })


  output$output_table<-renderTable(data.frame(widgets=input$widgets,quantities=rep(999,len_widgets())))


  output$widget_quantities <- renderUI({

    code<-list()


    for( item in input$widgets)
    {
      inp_name<-paste("inp",item,sep = "_")
      inp_display_name<-paste("Quantity of",item,sep = " ")
      code<-list(code,numericInput(inp_name, inp_display_name,value=300))
    }
    return(code)
  })


}



count_widgets<-function(inp=c())
{
  return(length(inp))
}

shinyApp(ui = ui, server = server)

Probably you want this:

  • You could make it cleaner not hardcoding all the widgets, but i think you can adapt it from here
  • also the quantities will reset when you update your widgets, but my Lunchbreak is over :D Let me know if you can solve that, the basic question should be answered.

If you need any docu let me know, I can add it later.

library(shiny)
x <- data.frame()
widget_list = c("Widget_A","Widget_B","Widget_C","Widget_D","Widget_E")
ui <- fluidPage(title = "Test Case for Dynamic Inputs",

                headerPanel(h3("Test Case for Dynamic Inputs")),
                sidebarPanel(width = 3,
                             selectInput("widgets","Select Widgets",choices=widget_list,multiple = TRUE)
                ),
                sidebarPanel(title="Scoring Outputs",width = 3,
                             h3(textOutput("title"))
                ),
                sidebarPanel(title="Dynamic  UI",width=3,
                             uiOutput("widget_quantities"),
                             h4(tableOutput("output_table"),style="color: red")

                )
)

server <- function(input, output) {

  global <- reactiveValues(Widget_A = 300, Widget_B = 300, Widget_C = 300, Widget_D = 300, Widget_E = 300)  

  output$title<-renderText("Test dynamic inputs")

  fn_run<-reactive({
    count_widgets(input$widgets)
  })

  observe({
    for(item in input$widgets){
      global[[item]] <- input[[paste("inp",item,sep = "_")]]
    }
  })

  output$output_table<-renderTable({
    data.frame(global$Widget_A, global$Widget_B, global$Widget_C, global$Widget_D, global$Widget_E)
  })

  output$widget_quantities <- renderUI({

    code<-list()
    for( item in input$widgets)
    {
      inp_name<-paste("inp",item,sep = "_")
      inp_display_name<-paste("Quantity of",item,sep = " ")
      code<-list(code,numericInput(inp_name, inp_display_name,value=300))
    }
    return(code)
  })
}
count_widgets<-function(inp=c())
{
  return(length(inp))
}

shinyApp(ui = ui, server = server)

So I haven't gotten the final solution yet but thought I'd post some progress I made so far as a partial answer in case it clarifies what I'm trying to do.

https://statspot.shinyapps.io/app_upload_test_v2/

在此处输入图片说明

This new version now sets the right data frame (and hence prints the right table) which takes the values (quantities) from the input dynamically instead of static 999 as before).

  output$output_table<-renderTable(data.frame(widgets=input$widgets,quantities=rep(input[["inp_WidgetA"]],len_widgets())))

Only flaw is that it is hardcoded to regurgitate whatever is entered as the quantity for Widget A.

What I'd like is to programatically have it loop and do this for whatever widgets are entered by the user.

Ideas?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM