我有一个
shiny
应用程序,其中有很多 inputs
连接到不同的部分; data
、plot
、legends
等。所有这些都存储在 input$
中,我希望有一个更好的概述,因此我使用 reactive
创建新值。例如
data_atr <- c("data_atr_1", "data_atr_2")
data_attributes <- map(data_atr, ~reactive({inputs[[.x]]})) |> setNames(data_atr)
这是“正确”的方法还是有更好的方法?因为我想继续使用
data_attributes
,因为我将使用 input
我的问题的第二部分;
How do you debug reactive values using browser()
?有时我需要调试我的 reactive
值,当我尝试将它们打印到控制台时,我收到以下错误:
Operation not allowed without an active reactive context.
• You tried to do something that can only be done from inside a reactive consumer.
如何将值打印到控制台?
我尝试将
browser()
放入reactive
内,但什么也没发生。我注意到当 reactive
位于 function
内时,它就会进入调试(见下文)。这是为什么?我也很困惑为什么我可以打印 rv
,它是反应性的而不会出现错误。
library(shiny)
library(purrr)
ui <- fluidPage(
numericInput("a", "a", 5),
numericInput("b", "b", 5),
textOutput("a_b")
)
server <- function(input, output, session) {
rv <- reactiveVal("test")
a_b_fun <- function(input, names = c("a", "b")){
reactive({
# browser() THIS WORKS
map(names, ~input[[.x]]) |> setNames(names)
})
}
f <- reactive({
# browser() # THIS DOES NOT WORK
map(c("a", "b"), ~input[[.x]]) |> setNames(names)
})
a_b_reactive <- a_b_fun(input = input)
a_b_sum <- eventReactive(a_b_reactive(), {
a_b_reactive()$a + a_b_reactive()$b
})
output$a_b <- renderText(a_b_sum())
}
shinyApp(ui, server)
如果您将
browser()
放在 server
中的某个位置并且它没有停止执行,则很可能是因为您放置的响应式应用程序没有执行。
在您的示例中,
a_b_fun
用于a_b_sum
,a_b_sum
输出为"a_b"
,因此将browser()
放入a_b_fun
将按预期工作,并且将在该情况下停止执行应用程序评估反应性。
但是,在您的示例中,反应式
f
未在应用程序中的任何地方使用,因此它甚至不会运行,因此 browser()
永远不会被评估。在 Shiny 中,只有实际用于用于应用程序中某些内容的响应式对象(例如被其他响应式使用,或用于输出)才会被执行,因此将 browser()
放入未使用的响应式中将不会执行任何操作。
要让
browser()
在 f
反应式中工作,请使用 f
作为测试输出,如 output$f <- renderText(f())
,并在 UI 中分配输出,以便运行该代码段并且浏览器将停止执行。
调试 Shiny 应用程序的另一个好技巧是将
message()
调用放入反应和输出中。这样,当每个元素被执行时,您将在控制台中收到消息。您还可以使反应打印数据或文本,但请记住为每个反应分配正确的输出,以便它们返回您期望的内容:
f <- reactive({
message("running f()") # show a message in console
# browser() # THIS DOES NOT WORK
result <- map(c("a", "b"), ~input[[.x]]) |> setNames(names)
print(result) # print result in console
return(result)
})
output$f <- renderText(f())