簡體   English   中英

Shiny 應用程序中定義的功能是否不搜索封閉環境?

[英]Do functions defined within Shiny apps not search the enclosing environment?

我有一個 Shiny 應用程序,它調用幾個自定義函數來響應點擊事件。 這些自定義函數使用多個反應值,我認為我不需要將所有這些反應值作為 arguments 傳遞給自定義函數,但似乎我需要。

我本來希望該應用程序的行為像正常的 R 一樣,其中自定義 function 將搜索直接環境,然后,在找不到變量時,將搜索封閉環境並向上 Z31A1FD140BE4BEFA2D11E121EC9A1 拋出一個錯誤. 相反,當 function 處理反應變量時,似乎function 中的代碼不知道在其外部定義的反應變量 這是真的?

由於identity_fun找不到input$click而崩潰的快速演示應用程序:

library(shiny)

identity_fun <- function(x){
  print(paste("Title's been changed", input$click, "times now"))
  x
}

ui <- fillPage(
  sidebarLayout(
    sidebarPanel(
      textInput("text", "Plot title here"),
      actionButton("click", "Click when ready to apply it")
    ),
    mainPanel(
      plotOutput("mainplot")
    )
  )
)

server <- function(input, output){
  input_text <- reactiveVal()
  observeEvent(input$click, {
    input_text(identity_fun(input$text))
  })
  output$mainplot <- renderPlot({
    plot(1, main = input_text())
  })
}

shinyApp(ui, server)

在基礎 R 中,可以輕松找到 function 之外的變量:

input <- list()
input$click <- 1
identity_fun("blah")
[1] "Title's been changed 1 times now"
[1] "blah"

在使用 Shiny 應用程序時,這種不同的行為讓我感到驚訝。

要修復上述應用程序,我可以將相關信息作為參數傳遞給identity_fun

identity_fun <- function(x, input_click){
  print(paste("Title's been changed", input_click, "times now"))
  x
}

observeEvent(input$click, {
    input_text(identity_fun(input$text, input$click))
  })

但我想知道這是否是最好的方法。 我意識到這可能是故意的行為,因為 function 自動檢測它使用input$click並在input$click更改時無效似乎很復雜,但 Shiny 以前對我來說很神奇。

將反應值傳遞給 function 是否有比將它們添加為 arguments 更好的方法?

上面示例的問題是, identity_fun是在服務器 function 之外定義的。 然而,Shiny 的input僅在服務器 function 內部可用(全局環境中沒有input變量。您可以通過 RStudio 的環境選項卡進行檢查)。

以下作品:

library(shiny)

ui <- fillPage(
  sidebarLayout(
    sidebarPanel(
      textInput("text", "Plot title here"),
      actionButton("click", "Click when ready to apply it")
    ),
    mainPanel(
      plotOutput("mainplot")
    )
  )
)

server <- function(input, output){
  identity_fun <- function(x){
    print(paste("Title's been changed", input$click, "times now"))
    x
  }
  input_text <- reactiveVal()
  observeEvent(input$click, {
    print(identity_fun(input$text))
  })
  output$mainplot <- renderPlot({
    plot(1, main = input_text())
  })
}

shinyApp(ui, server)

因此,在 Shiny 應用程序中定義的函數就像在 R 中的其他任何地方一樣工作。

但是,我建議始終明確傳遞 function 參數,以使您的代碼更具可讀性。

也請檢查這篇文章

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM