假设我想拥有renderDataTable
的自定义版本,我将其命名为myRenderDataTable
,并绕着renderDataTable
进行工作:
library(shiny)
runApp(list(
ui = basicPage(
actionButton("button", "Increase input"),
tabsetPanel(
tabPanel("table1", shiny::dataTableOutput("table1")),
tabPanel("table2", shiny::dataTableOutput("table2")),
tabPanel("table3", shiny::dataTableOutput("table3"))
)
),
server = function(input, output) {
myRenderDataTable <- function(a) {
renderDataTable(
data.frame(x = a, y = a^2, z = a^3),
options = list(bPaginate = as.logical(a %% 2))
)
}
output$table1 <- myRenderDataTable(input$button)
output$table2 <- myRenderDataTable(input$button + 1)
output$table3 <- myRenderDataTable(input$button + 2)
}
))
不幸的是,myRenderDataTable
似乎不像renderDataTable
那样被动。单击Increase input
按钮应该会更改表值,但不会。
那么出了什么问题?
reactive
:执行output$table1 <- reactive(myRenderDataTable(input$button))
)会导致:
Error during wrapup: evaluation nested too deeply: infinite recursion / options(expressions=)?
Error : evaluation nested too deeply: infinite recursion / options(expressions=)?
observe
:执行observe(output$table1 <- myRenderDataTable(input$button))
对问题没有影响
答案 0 :(得分:3)
问题在于input$button
被“急切地”评估 - 即input$button + 1
在第一次运行时评估为2,然后再也不会改变。您可以通过明确地将其input$button
更改为library(shiny)
runApp(list(
ui = basicPage(
actionButton("button", "Increase input"),
tabsetPanel(
tabPanel("table1", shiny::dataTableOutput("table1")),
tabPanel("table2", shiny::dataTableOutput("table2")),
tabPanel("table3", shiny::dataTableOutput("table3"))
)
),
server = function(input, output) {
myRenderDataTable <- function(a) {
renderDataTable(
data.frame(x = a(), y = a()^2, z = a()^3),
options = list(bPaginate = as.logical(a() %% 2))
)
}
output$table1 <- myRenderDataTable(reactive(input$button))
output$table2 <- myRenderDataTable(reactive(input$button + 1))
output$table3 <- myRenderDataTable(reactive(input$button + 2))
}
))
来进行评估:
{{1}}
答案 1 :(得分:1)
我认为你低估了渲染*功能中有多少魔法。通过查看此示例,我认为您不想要自定义renderDataTable
函数,我认为您需要一个自定义函数来构建表格,然后您可以将其传递给内置renderDataTable
。我认为这样做你想要的,包装只是在相反的顺序(即,反应式表达式中的自定义函数):
library(shiny)
runApp(list(
ui = basicPage(
actionButton("button", "Increase input"),
tabsetPanel(
tabPanel("table1", dataTableOutput("table1")),
tabPanel("table2", dataTableOutput("table2")),
tabPanel("table3", dataTableOutput("table3"))
)
),
server = function(input, output) {
myDataTable <- function(a) {
data.frame(x = a, y = a^2, z = a^3)
}
output$table1 <- renderDataTable(myDataTable(input$button))
output$table2 <- renderDataTable(myDataTable(input$button + 1))
output$table3 <- renderDataTable(myDataTable(input$button + 2))
}
))