r语言 - Shiny:使用 do.call 运行渲染族函数



我想用do.call来运行渲染族函数,比如renderPrint()。下面的代码不起作用:

rm(list=ls())
library(shiny)
ui <- fluidPage(
  selectInput("select", label = h3("Select box"), 
              choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3), 
              selected = 1),
  hr(),
  fluidRow(column(3, verbatimTextOutput("value")))
)
server <- function(input, output, session) {
  output$value <- do.call("renderPrint", list({ input$select }))
}
shinyApp(ui, server)

错误:

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.)
Stack trace (innermost first):
    45: .getReactiveEnvironment()$currentContext
    44: .subset2(x, "impl")$get
    43: $.reactivevalues
[...]

如何实现这一点?我猜这与环境和懒惰评估有某种联系,所以关闭可能是解决方案,但这只是猜测......

我找到了一种基于 SO 的答案来构建它的方法。关键部分是使用 alist 而不是 list .从文档中:

alist 处理其参数,就好像它们描述函数参数一样。因此,不会计算值,并且允许没有值的标记参数,而列表只是忽略它们。alist最常与正式形式一起使用。

rm(list=ls())
library(shiny)
ui <- fluidPage(    
  selectInput("select", label = h3("Select box"), 
              choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3), 
              selected = 1),
  hr(),
  fluidRow(column(3, verbatimTextOutput("value")))    
)
server <- function(input, output, session) {          
  output$value <- do.call(
    renderPrint, 
    alist(input$select)
  )
}
shinyApp(ui, server)

或者,您可能可以在renderPrint中使用 quoted 参数并用quote包裹您的表达式,但我没有运气使用这种方法。

注意

:我试图在评论中添加格雷戈尔的答案,但有点失败了..阅读他的第一个!

默认情况下,do.call在构造调用时计算其参数。

但是您可以指定quote = TRUE使参数不被评估:

output$value <- do.call(renderPrint, list(quote(input$select), quoted = TRUE), quote = TRUE)

但更简单的是只在调用中使用带引号的参数:

output$value <- do.call(renderPrint, list(quote(input$select)))

然后,在调用时计算带引号的表达式,并且您不会在反应上下文之外计算input$select

最新更新