简体   繁体   中英

R Shiny uiOutput to display the label from the input value from another uiOutput

The title may be very confusing but I will try to explain my problem below in detail. I use the book "mastering shiny" section 10, "Dynamic UI" as guidance. The libraries used in R is

library(shiny)
library(tidyverse)
library(purrr)

I have a numericInput labelled as Number of modalities/ subspecialties required .
I have a uiOutput called modality in response that can have more modalities if the input from the numericInput changes. See below pictures if the number changes to 2, there will be 2 modalities boxes rather than 1.

模态 模态2

The code for the above to work is listed below

# UI
numericInput("No_modalities", label = "Number of modalities/
                              subspecialties required",
                              value = 1, min = 1, max = 100, step = 1)
uiOutput("modality")

# Server
modality_names <- reactive(paste0("Modality ", seq_len(input$No_modalities)))

output$modality <- renderUI({
    map(modality_names(), ~ textInput(.x, label = paste(.x," Name"),
                                         value = isolate(input[[.x]])))
  })

Now I want another uiOutput to have the labels as the input inside the Modality Name. Here's how I approached the problem. I created another uiOutput called ui_modality_minutes , but for the labels, I want to use the labels from the input from modality_names() . Please see below picture to better understand my aim. I want the input1 model 1 to be the first label, and input2 model 2 to be the second label, but my code will add model 1 and model 2 together rather than separately.

# UI
uiOutput("ui_modality_minutes")

# Server
modality_minutes <- reactive(paste0("Modality minutes ",
                                      seq_len(input$No_modalities)))

output$ui_modality_minutes <- renderUI({
    map(modality_minutes(), ~ numericInput(.x, 
                          label = map(modality_names(),~input[[.x]]),
                          value = isolate(input[[.x]])))
  })

模组1 模组2

Reproducible codes are shown below,

library(shiny)
library(tidyverse)
library(purrr)

ui <- fluidPage(
  fluidRow(
  numericInput("No_modalities", label = "Number of modalities/
                              subspecialties required",
               value = 1, min = 1, max = 100, step = 1)),
  fluidRow(
    uiOutput("modality")
  ),
  fluidRow(
    uiOutput("ui_modality_minutes")
  )
)

server <- function(input, output, session) {
  modality_names <- reactive(paste0("Modality ", seq_len(input$No_modalities)))
  modality_minutes <- reactive(paste0("Modality minutes ",
                                      seq_len(input$No_modalities)))
  
  output$modality <- renderUI({
    map(modality_names(), ~ textInput(.x, label = paste(.x," Name"),
                                      value = isolate(input[[.x]])))
  })
  output$ui_modality_minutes <- renderUI({
    map(modality_minutes(), ~ numericInput(.x, 
                                           label = map(modality_names(),~input[[.x]]),
                                           value = isolate(input[[.x]])))
  })
}

shinyApp(ui, server)

Your last map function needs to be a map2 to simultaneously handle the generation of the inputId and the label . To get a character vector of the labels, I nest a map_chr into the map2 function:

library(purrr)
library(shiny)

ui <- fluidPage(
  numericInput("No_modalities", label = "Number of modalities/
                              subspecialties required",
               value = 1, min = 1, max = 100, step = 1),
  uiOutput("modality"),
  uiOutput("ui_modality_minutes")
)

server <- function(input, output, session) {
  modality_names <- reactive(paste0("Modality ", seq_len(input$No_modalities)))
  
  output$modality <- renderUI({
    map(modality_names(), ~ textInput(.x, label = paste(.x," Name"),
                                      value = isolate(input[[.x]])))
  })
  modality_minutes <- reactive(paste0("Modality minutes ",
                                      seq_len(input$No_modalities)))
  
  output$ui_modality_minutes <- renderUI({
    map2(modality_minutes(), map_chr(modality_names(),~input[[.x]]%||% ""), ~ numericInput(.x, 
                                           label = .y,
                                           value = isolate(input[[.x]])))
  })
}

shinyApp(ui, server)

You sometimes get an error when an input in map_chr(modality_names(),~input[[.x]]) is NULL , but for your functionality it doesn't make a difference (then no name is shown).

Edit

Now including Subaru Spirit's solution to get rid of NULL

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