有没有办法在 Shiny (R) 中为 renderUI 制作包装函数?
Is there a way to make a wrapper function for renderUI in Shiny (R)?
我需要使用 renderUI
根据另一个输入值创建多个输入选项。我想将 renderUI
中的所有内容作为一个函数包装起来,这样我就可以将其应用于许多类似的输入。这是一个简化的示例(对我有用,但我不想多次重复 renderUI
部分,因为我还有许多其他输入,例如 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)
问题是,当我尝试将其包装到函数中时,renderUI
创建的输出在我更改输入值时停止更新。这是对我不起作用的代码:
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)
虽然我看不出这样做有什么意义,因为即使你将那个部分移到一个函数中,你仍然必须定义每个 sliderInput
,这是一种方法。
关键是你应该包装输入而不是 renderUI
,因为你需要反应式表达式才能更新输入,反应式只能在另一个反应式或 render*
函数中工作
library(shiny)
ui <- fluidPage(
fluidRow(
selectInput(
inputId = 'i1',
label = 'choice 1',
choices = list(5, 10)
),
uiOutput('o1')
)
)
server <- function(input, output, session) {
wrapper <- reactive({
function(i){
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
)
)
}
})
output$o1 <- renderUI(wrapper()(input$i1))
}
shinyApp(ui = ui, server = server)
这是一个可能的选择:
library(shiny)
create_sliders <- function(i) {
fluidRow(
column(
width = 12,
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({
create_sliders(input$i1)
})
}
shinyApp(ui = ui, server = server)
我需要使用 renderUI
根据另一个输入值创建多个输入选项。我想将 renderUI
中的所有内容作为一个函数包装起来,这样我就可以将其应用于许多类似的输入。这是一个简化的示例(对我有用,但我不想多次重复 renderUI
部分,因为我还有许多其他输入,例如 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)
问题是,当我尝试将其包装到函数中时,renderUI
创建的输出在我更改输入值时停止更新。这是对我不起作用的代码:
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)
虽然我看不出这样做有什么意义,因为即使你将那个部分移到一个函数中,你仍然必须定义每个 sliderInput
,这是一种方法。
关键是你应该包装输入而不是 renderUI
,因为你需要反应式表达式才能更新输入,反应式只能在另一个反应式或 render*
函数中工作
library(shiny)
ui <- fluidPage(
fluidRow(
selectInput(
inputId = 'i1',
label = 'choice 1',
choices = list(5, 10)
),
uiOutput('o1')
)
)
server <- function(input, output, session) {
wrapper <- reactive({
function(i){
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
)
)
}
})
output$o1 <- renderUI(wrapper()(input$i1))
}
shinyApp(ui = ui, server = server)
这是一个可能的选择:
library(shiny)
create_sliders <- function(i) {
fluidRow(
column(
width = 12,
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({
create_sliders(input$i1)
})
}
shinyApp(ui = ui, server = server)