用于呈现函数的反应参数

时间:2018-01-05 15:37:16

标签: r shiny flexdashboard

我在flexdashboard中有一个表,其列数可以更改。我可以动态计算列的对齐方式(默认对齐将$23.45视为字符向量,因此左对齐值,尽管它是一个数字,应该是右对齐的)。问题是我无法将此对齐方式作为renderTable的值传递回align,因为它是一个无效值。

如何将反应对齐传递回renderTable函数的align参数? (或者让我使用反应性对齐渲染表格的替代方案)

MWE

---
title: "test"
output: flexdashboard::flex_dashboard
runtime: shiny
---

```{r}
library(flexdashboard)
library(shiny)
```

Inputs {.sidebar}
-------------------------------------

```{r}
selectInput(
    "ncols", 
    label = "How many columns?",
    choices = 1:5, 
    selected = 5
)
```  

Column  
-------------------------------------

### Test

```{r}
nc <- reactive({input$ncols})
aln <- reactive({substring('lllrr', 1, nc())})

renderTable({
    x <- CO2[1:5, seq_len(nc()), drop = FALSE]
    x[, 1] <- as.character(x[, 1])
    x[3, 1] <- '<b>Mc1</b>'
    x
}, align = aln(), sanitize.text.function = function(x) x)
```

结果:

 Warning: Error in .getReactiveEnvironment()$currentContext: Operation not 
 allowed without an active reactive context. (You tried to do something 
 that can only be done from inside a reactive expression or observer.)

2 个答案:

答案 0 :(得分:7)

尝试在aln()中包裹renderText(...),即

renderTable({
    x <- CO2[1:5, seq_len(nc()), drop = FALSE]
    x[, 1] <- as.character(x[, 1])
    x[3, 1] <- '<b>Mc1</b>'
    x
}, align = renderText(aln()), 
   sanitize.text.function = function(x) x)

答案 1 :(得分:6)

首先,发生的具体错误是非常正确的。函数renderTable只能在其第一个参数renderTable({ ... }, ...)中保存反应式表达式。所有其他东西必须是普通物体。因此,设置一个反应值aln()实际上是在常规环境中放置reactive。或者,从reactive本身的角度来看,它被评估为没有活动的反应上下文,就像它在错误消息中所说的那样。

使这些事情成为反应的解决方法是renderTable的包装,即renderUI。在renderUI内,我们可以反应性地塑造包括对齐在内的整个表格渲染。 (解决方案部分改编自here。)

以下是您需要替换renderTable的内容:

renderUI({
  output$table <- renderTable({
      x <- CO2[1:5, seq_len(isolate(nc())), drop = FALSE]
      x[, 1] <- as.character(x[, 1])
      x[3, 1] <- '<b>Mc1</b>'
      x
  }, align = aln(), sanitize.text.function = function(x) x)

  tableOutput("table")
})

快速解释:使用output变量就像在常规闪亮环境中一样,如果不是降价。 renderUI将呈现的内容是对renderTable的引用,我们将每次从头开始重新创建。{/ p>

注意:我在isolate内使用了renderTable。原因如下:renderTable具有反应性,如果nc()发生变化,则会更新。但这可能发生在周围的renderUI对变化作出反应之前。您会看到,在此中间步骤中,renderTable会尝试绘制具有不同列数的data.frame,但align仍然是以前的列数。抛出错误,因为它们不匹配。隔离内部nc()会阻止内部renderTable更新。但这没关系,因为外部的renderUI无论如何都要这样做,一旦轮到它更新。