¿Hay alguna forma de crear una función envolvente para renderUI en Shiny (R)?
Necesito usar renderUI
para crear múltiples opciones de entrada basadas en el valor de otra entrada. Quiero envolver todo dentro de renderUI
como una función para poder aplicar esto a muchas entradas similares. Aquí hay un ejemplo simplificado (que funciona para mí, pero no quiero repetir la parte de renderUI
muchas veces, porque tengo muchas otras entradas como i1
):
library(shiny)
ui <- fluidPage(
fluidRow(
selectInput(
inputId = 'i1',
label = 'choice 1',
choices = list(5, 10)
),
uiOutput('o1')
)
)
server <- function(input, output, session) {
output$o1 <- renderUI(
fluidRow(
sliderInput(
inputId = 's1',
label = 'slider 1',
min = 0, max = as.numeric(input$i1) * 10,
value = 0.5
),
sliderInput(
inputId = 's2',
label = 'slider 2',
min = 0, max = as.numeric(input$i1) * 100,
value = 0.5
)
)
)
}
shinyApp(ui = ui, server = server)
El problema es que cuando intenté envolverlo en una función, la salida creada por renderUI
deja de actualizarse cuando cambio el valor de entrada. Aquí está el código que no funciona para mí:
library(shiny)
renderUI_warpper <- function(i){
renderUI(
fluidRow(
sliderInput(
inputId = 's1',
label = 'slider 1',
min = 0, max = as.numeric(i) * 10,
value = 0.5
),
sliderInput(
inputId = 's2',
label = 'slider 2',
min = 0, max = as.numeric(i) * 100,
value = 0.5
)
)
)
}
ui <- fluidPage(
fluidRow(
selectInput(
inputId = 'i1',
label = 'choice 1',
choices = list(5, 10)
),
uiOutput('o1')
)
)
server <- function(input, output, session) {
output$o1 <- renderUI_warpper(input$i1)
}
shinyApp(ui = ui, server = server)
davy.ai
El problema con el código actualizado es que
renderUI_wrapper
solo se ejecuta una vez cuando se crea la salida por primera vez, y no se vuelve a ejecutar cuando cambia el valor de entrada. Para que funcione, necesitamos envolver la llamada a la función en una expresiónreactive
, que volverá a ejecutar la función siempre que cambie el valor de entrada. Aquí está el código modificado que debería funcionar:En este código modificado, hemos eliminado la función
renderUI
de la funciónrenderUI_wrapper
y, en su lugar, la estamos llamando dentro de la funciónrenderUI
de la salida. Además, hemos envuelto la llamada a la funciónrenderUI_wrapper
dentro de una expresiónreactive
, para que se vuelva a ejecutar siempre que cambie el valor de entrada.