在布局之间切换与闪亮的反应

时间:2015-10-14 23:46:11

标签: r shiny reactive-programming

如何根据用户输入在Shiny中切换页面布局?例如,我想在侧边栏布局和井面布局之间切换,以使图形能够跨越整个页面。

到目前为止我的工作似乎已接近工作,但我认为问题在于我无法重用从renderUI创建的接口。这是一个例子,

library(shiny)

shinyApp(
    shinyUI(
        fluidPage(
            radioButtons('layout', 'Layout:', choices=c('Sidebar', 'WellPanel'), inline=TRUE),
            conditionalPanel(
                condition = "input.layout == 'Sidebar'",
                uiOutput('sidebarUI')
            ),
            conditionalPanel(
                condition = "input.layout == 'WellPanel'",
                uiOutput('wellUI')
            )
        )
    ),
    shinyServer(function(input, output) {
        output$sidebarUI <- renderUI({
            sidebarLayout(
                sidebarPanel(
                    uiOutput('ui')
                ),
                mainPanel(
                    plotOutput('plot')
                )
            )
        })

        output$wellUI <- renderUI({
            fluidRow(
                column(12, plotOutput('plot')),
                column(12, wellPanel(uiOutput('ui')))
            )
        })

        output$ui <- renderUI({
            list(
                checkboxInput('inp1', 'Some stuff'),
                sliderInput('inp2', 'Some more stuff', 0, 10, 5)
            )
        })

        output$plot <- renderPlot({ plot(1) })
    })
)

如果任何一个条件面板被注释掉,那么另一个可以工作,但只有一个适用于两个条件面板。这是怎么做到的?

1 个答案:

答案 0 :(得分:2)

您好,您无法在ui中调用两次(或更多)输出,这就是为什么这不起作用,而是您可以像这样在服务器中完成所有工作:

library(shiny)

shinyApp(
  shinyUI(
    fluidPage(
      radioButtons('layout', 'Layout:', choices=c('Sidebar', 'WellPanel'), inline=TRUE),
      uiOutput('general_ui')
    )
  ),
  shinyServer(function(input, output) {
    output$general_ui <- renderUI({
      if (input$layout == "Sidebar") {
        sidebarLayout(
          sidebarPanel(
            uiOutput('ui')
          ),
          mainPanel(
            plotOutput('plot')
          )
        )
      } else if (input$layout == "WellPanel") {
        fluidRow(
          column(12, plotOutput('plot')),
          column(12, wellPanel(uiOutput('ui')))
        )
      }
    })

    output$ui <- renderUI({
      list(
        checkboxInput('inp1', 'Some stuff'),
        sliderInput('inp2', 'Some more stuff', 0, 10, 5)
      )
    })

    output$plot <- renderPlot({ plot(1) })
  })
)

但是有一个问题,当你在布局之间切换时,输入小部件会重新初始化......

但你可以用这样的东西来解决它:

output$ui <- renderUI({
  list(
    checkboxInput('inp1', 'Some stuff'),
    if (is.null(input$inp2)) {
      sliderInput('inp2', 'Some more stuff', 0, 10, 5)
    } else {
      sliderInput('inp2', 'Some more stuff', 0, 10, input$inp2)
    }
  )
})

在创建窗口小部件之前,您必须检查该值是否已经存在,以比上述更紧凑的方式执行此操作:

output$ui <- renderUI({
      list(
        checkboxInput(inputId = "inp1", label = 'Some stuff', value = input$inp1 %||% FALSE),
        sliderInput(inputId = "inp2", label = 'Some more stuff', min = 0, max = 10, value = input$inp2 %||% 5)
      )
    })

%||%函数定义如下:

`%||%` <- function(a, b) {
  if (!is.null(a)) a else b
}
相关问题