我在flexdashboard中有一个表,其列数可以更改。我可以动态计算列的对齐方式(默认对齐将$23.45
视为字符向量,因此左对齐值,尽管它是一个数字,应该是右对齐的)。问题是我无法将此对齐方式作为renderTable
的值传递回align
,因为它是一个无效值。
如何将反应对齐传递回renderTable
函数的align
参数? (或者让我使用反应性对齐渲染表格的替代方案)
---
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.)
答案 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
无论如何都要这样做,一旦轮到它更新。