Home > Software design >  Problem with running while loop on shiny R
Problem with running while loop on shiny R

Time:03-01

My project would be to create a shiny app that does the following:

  1. ask the user how many strings he would like to insert (a number between 1 and 6)
  2. based on the number I would like to obtain, with a for or while loop, enter the strings to the user.

The first point I succeeded, the problem lies in the second. I don't understand how to save the value obtained in the first point as a number so that I can use it in a while (or for) loop. I enter my attempt wrong.

library(shiny)

ui <- fluidPage(
        radioButtons(
            "radio", 
            label = HTML(
                '<FONT>Conjoint analysis</FONT>
                <b> How many attributes do you want to insert??</b>'),
            choices = list("1" = 1, "2" = 2, "3"=3, "4"=4, "5"=5, "6"=6),
            inline = T)
      ),

   
server <- function(input, output){
              output$value <- renderPrint({
                  i<-input$radio,
                  while(i>=0){
                      return(textInput(
                          inputId="title",
                          label= "Scrivi:")),
                      i=i-1
                  }
              })
          } 


shinyApp(ui = ui, server = server)

CodePudding user response:

Here is an example that may be helpful. Add generic uiOutput to your ui and then renderUI (as mentioned in comments) that can dynamically create the textInput fields you need. I would use lapply instead of a loop.

In addition, I added renderTable that will display the entered values taken from the inputs for demonstration.

library(shiny)

ui <- fluidPage(
  radioButtons(
    "radio", 
    label = HTML(
      '<FONT>Conjoint analysis</FONT>
       <b>How many attributes do you want to insert?</b>'),
    choices = 1:6,
    inline = T),
  uiOutput("input_ui"),
  tableOutput("table")
)

server <- function(input, output){
  
  output$input_ui <- renderUI({
    lapply(1:input$radio, function(i) {
      textInput(paste0("title_", i), label = paste0("Scrivi:", i))
    })
  })
  
  output$table <- renderTable({
    data.frame(lapply(1:input$radio, function(i) {
      input[[paste0("title_", i)]]
    }))
  })
  
}

shinyApp(ui = ui, server = server)

Edit: Here is an example with side-by-side inputs. Here I used verbatimTextOutput paired with renderPrint to show the input values as an alternative for demonstration.

library(shiny)

ui <- fluidPage(
  radioButtons(
    "radio", 
    label = HTML(
      '<FONT>Conjoint analysis</FONT>
       <b>How many attributes do you want to insert?</b>'),
    choices = 1:6,
    inline = T
  ),
  uiOutput("input_ui"),
  verbatimTextOutput("text")
)

server <- function(input, output){
  
  output$input_ui <- renderUI({
    lapply(1:input$radio, function(i) {
      splitLayout(
        textInput(paste0("title_", i), label = paste0("Scrivi:", i)),
        selectInput(paste0("lis_", i), label = paste0("Inserisci il numero di livelli:", i), choices = 1:5),
        tags$head(tags$style(HTML("
          .shiny-split-layout > div {
            overflow: visible;
          }
        ")))
      )
    })
  })
  
  output$text <- renderPrint({
    lapply(1:input$radio, function(i) {
      paste(input[[paste0("title_", i)]], input[[paste0("lis_", i)]])
    })
  })
  
}

shinyApp(ui = ui, server = server)

CodePudding user response:

This is my code

library(shiny)

ui <- fluidPage(
   radioButtons(
     "num", 
    label = HTML(
       '<b>Quanti attributi vuoi inserire?</b>'),
    choices = 1:6,
    ),
  uiOutput("input_ui"))

server <- function(input, output){
 
 output$input_ui <- renderUI({                                     
    lapply(1:input$num, function(i) { 
                                      
      splitLayout(
         textInput(paste0("att", i), label = paste0("Attributo ", i)),
        
         radioButtons(
          paste0("liv", i), 
          label = paste0("Inserisci il numero di livelli "),
          choices = 1:5,
          inline = F),
          tags$head(tags$style(HTML(" .shiny-split-layout > div {overflow: visible;} "))),
        )
      
       r<- as.integer(output$liv),
       lapply(1:liv, function(l) {
         textInput(paste0("livello", l), label = paste0("Livello ", l))
       }})})}

shinyApp(ui = ui, server = server)
  • Related