r - 通过 Shiny 在布局之间进行响应式(Reactive)切换

标签 r shiny reactive-programming

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

到目前为止,我所拥有的似乎即将开始工作,但我认为问题是我无法重用从 renderUI 创建的接口(interface)。这是一个例子,

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) })
    })
)

如果其中一个条件面板被注释掉,则另一个可以工作,但只有一个条件面板可以与两个条件面板一起工作。这是如何完成的?

最佳答案

嗨,您不能在用户界面中调用输出两次(或更多次),这就是为什么这不起作用,相反您可以像这样在服务器中完成所有工作:

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
}

关于r - 通过 Shiny 在布局之间进行响应式(Reactive)切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33137546/

相关文章:

R ggplot2 : Error when plotting facet grid that doesn't occur for single plot

R ggplot2 用下标和波浪号注释

r - 用于多个输入的 Shiny updateSelectInput

r - Shiny 的 : How to modify reactive object

r - 如何阻止合并将字符转换为因子?

r - 文件错误(文件名, "r",编码=编码): cannot open the connection

r - 使用用户输入、 Shiny 、renderImage 更改图像

java - 如何在 RxJava 中返回聚合——collect() 是正确的方法吗?

haskell - react 香蕉 : consume parametrized call to an external API

reactive-programming - Flow API 是否正在取代 Observer 和 Observable