将 conditionalPanel 与 flexdashboard 和 runtime shiny 结合使用,以根据列的存在有条件地切换输出类型

Use of conditionalPanel with flexdashboard and runtime shiny to conditionally switch output type based upon column presence

我正在尝试使用 conditionalPanel 在 flexdashboard 选项卡中有条件地切换 shiny 输出渲染类型,如 Shiny documentation here, by using a reactive output object and making sure it is returned to the browser by using outputOptions(output, [myOutputName], suspendWhenHidden = FALSE). This approach has been suggested in several SO anwsers (e.g. here and here 中所述,以获得成熟的 Shiny 应用程序,但我找不到他们的示例在 Shiny 文档中使用(R markdown)。本质上,我想测试一个选定的数据集是否有特定的列(即该列不是 null),并且 使 UI 根据是否存在有条件地渲染绘图本专栏。在下面的玩具数据中,列表中有已知数量的项目,并且知道哪些项目有缺失的列。当 运行 本地文档时,所需的行为就在那里(即集合将根据选择切换并且条件面板似乎显示我希望它显示的内容),但检查器仍然显示我列出的错误以下。在 rstudio connect 上发布会导致界面不被渲染(我想是因为同样的错误)。检查器中的这些错误(Error evaluating expression: ouput.evalseplen == trueUncaught ReferenceError: ouput is not defined)是已知的闪亮错误吗?还是有更深层次的事情发生?

---
title: "fdb_reprex"
author: "FMKerchof"
runtime: shiny
output:
  flexdashboard::flex_dashboard:
    orientation: rows
    inlcudes:
      navbar:
        - { title: "More info", href: "https://github.com/FMKerckhof", align: right }
fontsize: 9pt
editor_options: 
  chunk_output_type: console
---

```{r setup, include=FALSE}
# Set knitr options ----
knitr::opts_chunk$set(echo = TRUE)
# load packages ----
library(shiny)
library(shinydashboard)
library(ggplot2)
library(plotly)
# toy dataset ----
inputlist <- list(fulliris=iris,
                  irisnoseplen=iris[,-1],
                  irisnopetlen=iris[,c(1,2,4,5)])
```

Inputs {.sidebar}
=======================================================================

```{r datasetsel, echo = FALSE}
renderUI(inputPanel(
  selectInput("datasetsel", label = "Choose your dataset:",
              choices = unique(names(inputlist)),
              selected = unique(names(inputlist))[2])
))

selected_data <- reactive({
  inputlist[[input$datasetsel]]
}) |>  bindEvent(input$datasetsel)
```

Sepals {data-icon="fa-leaf"}
===================================== 

Row {.tabset}
-------------------------------------

### Sepal widths

```{r sepwidthplotly, echo=FALSE}
output$p1 <- renderPlotly({
  req(selected_data())
  p1 <- selected_data() |>
    ggplot(aes(y=Sepal.Width,fill=Species,x=Species)) + geom_boxplot() + theme_bw()
  ggplotly(p1)
})

plotlyOutput("p1", width = "auto", height = "auto") 
```

### Sepal lengths

```{r seplenplotly, echo=FALSE}
output$p2 <- renderPlotly({
  if(!is.null(selected_data()$Sepal.Length)){
  p2 <- selected_data() |>
    ggplot(aes(y=Sepal.Length,fill=Species,x=Species)) + geom_boxplot() + theme_bw()
  ggplotly(p2)
  }
})




output$noseplentext <- renderText({
  if(is.null(selected_data()$Sepal.Length)){
    "No Sepal Lengths in the selected dataset"
  }
})

output$evalseplen <- reactive({
  return(is.null(selected_data()$Sepal.Length))
})

outputOptions(output, "evalseplen", suspendWhenHidden = FALSE)


conditionalPanel(condition = "ouput.evalseplen == true",
                 textOutput("noseplentext"))
conditionalPanel(condition = "ouput.evalseplen == false",
                 plotlyOutput("p2",width="auto",height="auto"))

```

从检查员那里可以清楚地看到输出没有定义,但我明确要求通过将 suspendWhenHidden 设置为 FALSE 来返回它

我的会话信息:R 4.1.2、shiny 1.7.1、flexdashboard 0.5.2、plotly 4.10.0、ggplot2 2.3.3.5

edit 感谢下面的回答,我意识到我在条件语句中打错了字(ouput 代替了 output),这是从错误消息中也很清楚。

我想我找到了解决方案,现在我不使用 show/hide 条件面板的 select 输入。

---
title: "fdb_reprex"
author: "FMKerchof"
runtime: shiny
output:
  flexdashboard::flex_dashboard:
    orientation: rows
    inlcudes:
      navbar:
        - { title: "More info", href: "https://github.com/FMKerckhof", align: right }
fontsize: 9pt
editor_options: 
  chunk_output_type: console
---

```{r setup, include=FALSE}
# Set knitr options ----
knitr::opts_chunk$set(echo = TRUE)
# load packages ----
library(shiny)
library(shinydashboard)
library(ggplot2)
library(plotly)
library(shinyjs)

# toy dataset ----
inputlist <- list(
  fulliris=iris,
  irisnoseplen=iris[,-1],
  irisnopetlen=iris[,c(1,2,4,5)]
  )
```

Inputs {.sidebar}
=======================================================================

```{r datasetsel, echo = FALSE}
renderUI(
  inputPanel(
    selectInput(
      "datasetsel", label = "Choose your dataset:",
      choices = unique(names(inputlist)),
      selected = unique(names(inputlist))[2]),
    )
  )

selected_data <- reactive({
  inputlist[[input$datasetsel]]
  }) |>  
  bindEvent(input$datasetsel)
```

Sepals {data-icon="fa-leaf"}
===================================== 

Row {.tabset}
-------------------------------------

### Sepal widths

```{r sepwidthplotly, echo=FALSE}
output$p1 <- renderPlotly({
  req(selected_data())
  
  p1 <- selected_data() |>
    ggplot(aes(y=Sepal.Width,fill=Species,x=Species)) + 
    geom_boxplot() + 
    theme_bw()
  
  ggplotly(p1)
})

plotlyOutput("p1", width = "auto", height = "auto") 
```

### Sepal lengths

```{r seplenplotly, echo=FALSE}
output$p2 <- renderPlotly({
  p2 <- selected_data() |>
      ggplot(aes(y = Sepal.Length, fill = Species, x = Species)) + 
      geom_boxplot() + 
      theme_bw()
    
    ggplotly(p2)

})

output$evalseplen = reactive({
  is.null(selected_data()$Sepal.Length)
})

output$noseplentext <- renderText({
  "No Sepal Lengths in the selected dataset"
})

outputOptions(output, "evalseplen", suspendWhenHidden = FALSE)


conditionalPanel(
  condition = "output.evalseplen", 
  textOutput("noseplentext")
  )

conditionalPanel(
  condition = "!output.evalseplen",
  plotlyOutput("p2",width="auto",height="auto")
  )

```

当你 select irisnopetlenfulliris

当你selectirisnoseplen