Create input ui elements for shiny app from existing data

Hello,

Say I have an existing data frame, and I want to create a succession of radioButton inputs to replicate this data, how do I / can I do this without copying and pasting and changing [1] to [2] and so on?

See below for a reprex to demonstrate how I am currently doing it - is there a better way to create multiple input elements from a dataframe/vector/list?

library(shiny)
library(tidyverse)

choices <- c("Yes", "No", "Maybe")

df <- tibble(car = rownames(mtcars),
             choices = sample(choices, 32, T))
    
ui <- fluidPage(

    radioButtons(df$car[1], label = h5(df$car[1]),
                 choices = choices, 
                 selected = df$choices[1], inline = T),
    radioButtons(df$car[2], label = h5(df$car[2]),
                 choices = choices, 
                 selected = df$choices[2], inline = T),
    radioButtons(df$car[3], label = h5(df$car[3]),
                 choices = choices, 
                 selected = df$choices[3], inline = T),
    
)

server <- function(input, output) {

    output$value <- renderPrint({ input$radio })
}

# Run the application 
shinyApp(ui = ui, server = server)

Thanks for asking an interesting question :slight_smile:

library(shiny)
library(tidyverse)
library(purrr)
choices <- c("Yes", "No", "Maybe")

df <- tibble(
  car = rownames(mtcars),
  choices = sample(choices, 32, T),
  inames = tolower(gsub(" ", "", rownames(mtcars)))
)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(uiOutput("radioholder")),
    mainPanel(
      textOutput("value"),
      tags$style(type = "text/css", "#value {white-space: pre-wrap;}")
    ) ## to respect \n linebreaks
  )
)

server <- function(input, output) {
  output$radioholder <- renderUI({
    map(df$inames, ~ {
      radioButtons(.,
        label = h5(.),
        choices = choices,
        selected = choices[1], inline = T
      )
    })
  })
  output$value <- renderText({
    printfunc <- function(x) {
      paste0(
        "radio ",
        x,
        " is set to ",
        input[[x]]
      )
    }

    paste0(map(df$inames, printfunc), collapse = "\n")
  })
}

# Run the application
shinyApp(ui = ui, server = server)
1 Like

Thank you, this is very helpful!

However, to get the full way there (and have the choices column of the data frame be reflected in the selection for each radioButton, I took your example a set further using map2, and you could use pmap and so on:

library(shiny)
library(tidyverse)
library(purrr)
choices <- c("Yes", "No", "Maybe")

df <- tibble(
  car = rownames(mtcars),
  choices = sample(choices, 32, T),
  inames = tolower(gsub(" ", "", rownames(mtcars)))
)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(uiOutput("radioholder")),
    mainPanel(
      textOutput("value"),
      tags$style(type = "text/css", "#value {white-space: pre-wrap;}")
    ) ## to respect \n linebreaks
  )
)

server <- function(input, output) {
  output$radioholder <- renderUI({
    map2(df$car, df$choices, ~ {
      radioButtons(.x,
                   label = h5(.x),
                   choices = choices,
                   selected = .y, inline = T
      )
    })
  })
  output$value <- renderText({
    printfunc <- function(x) {
      paste0(
        "radio ",
        x,
        " is set to ",
        input[[x]]
      )
    }
    
    paste0(map(df$inames, printfunc), collapse = "\n")
  })
}

# Run the application
shinyApp(ui = ui, server = server)

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.