模块化 R Shiny 代码:模块中的 ObserveEvent 函数
Modularizing R Shiny code: ObserveEvent function in module
我正在努力提高 R Shiny 中我的 app.R 代码的可用性,它变得很长。
基本上,我想创建一个模块 (infras.R) 来包含大量链接到 checkboxInputs 的 observeEvent 函数。
我知道我需要在 app.R 中获取模块,将 observeEvent 包装在一个函数中,在 observeEvent 函数中包含用于输入 ID 的名称空间 (ns),并为该函数插入一个 callModule。我还将 callModule 包装在一个 ObserveEvent 中,以便它的功能持续存在并且不会在启动 webapp 后仅触发一次。
在运行app.R上输出了以下错误,但我不知道如何解决:
Warning: Error in proxy: could not find function "proxy"
81: eval
80: eval
79: %>%
78: module [infras.R#153]
73: callModule
72: observeEventHandler
1: runApp
感谢您对此的帮助,因为我发现很难找到有关如何执行此操作的文献。
我的 R 脚本中的关键片段。
infras.R(更新):
icons_pow <- awesomeIcons(
iconColor = 'white',
markerColor = 'green',
text = "m"
)
mod <- function(input, output, session, pow_id, prox){
observeEvent(pow_id(),{
if(pow_id() != 0){
pow_id <- readOGR("../geospatial_files/ind", layer = "plants")
pow_iddf <- as.data.frame(pow_id)
prox %>%
addAwesomeMarkers(lng=pow_iddf$coords.x1, lat=pow_iddf$coords.x2, group = "pow_idg", icon=icons_pow,
label = paste(pow_iddf$Name,pow_iddf$Power_type,sep = ", "))
}
else {prox %>% clearGroup("pow_idg") %>% removeControl(layerId="pow_idc")
}
}
)
}
app.R(更新):
...
source("infras.R")
...
server <- function(input, output, session) {
...
proxy <- leafletProxy("map")
callModule(mod, "mod", reactive(input$pow_id), proxy)
})
...
}
您需要将 input
对象包装到 reactive
中,并将其用作模块的 input 参数。另一个输入参数是您的传单代理。在模块内,您可以使用 observe
更改您的代理,然后立即更新:
library(shiny)
library(leaflet)
library(RColorBrewer)
# The module containing the observer. Input is the reactive handle of legend input and the proxy
mod <- function(input, output, session, legend, prox){
observe({
prox %>% clearControls()
if (legend()) {
prox %>% addLegend(position = "bottomright",
pal = colorNumeric("Blues", quakes$mag), values = ~mag
)
}
})
}
ui <- bootstrapPage(
checkboxInput("legend", "Show legend", TRUE),
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%")
)
server <- function(input, output, session) {
output$map <- renderLeaflet({
pal <- colorNumeric("Blues", quakes$mag)
leaflet(quakes) %>% addTiles() %>%
addCircles(radius = ~10^mag/10, weight = 1, color = "#777777",
fillColor = ~pal(mag), fillOpacity = 0.7, popup = ~paste(mag)) %>%
fitBounds(~min(long), ~min(lat), ~max(long), ~max(lat))
})
# This is the handle for map
proxy <- leafletProxy("map", data = quakes)
callModule(mod, "mod", reactive(input$legend), proxy)
}
shinyApp(ui, server)
我正在努力提高 R Shiny 中我的 app.R 代码的可用性,它变得很长。
基本上,我想创建一个模块 (infras.R) 来包含大量链接到 checkboxInputs 的 observeEvent 函数。
我知道我需要在 app.R 中获取模块,将 observeEvent 包装在一个函数中,在 observeEvent 函数中包含用于输入 ID 的名称空间 (ns),并为该函数插入一个 callModule。我还将 callModule 包装在一个 ObserveEvent 中,以便它的功能持续存在并且不会在启动 webapp 后仅触发一次。
在运行app.R上输出了以下错误,但我不知道如何解决:
Warning: Error in proxy: could not find function "proxy"
81: eval
80: eval
79: %>%
78: module [infras.R#153]
73: callModule
72: observeEventHandler
1: runApp
感谢您对此的帮助,因为我发现很难找到有关如何执行此操作的文献。
我的 R 脚本中的关键片段。
infras.R(更新):
icons_pow <- awesomeIcons(
iconColor = 'white',
markerColor = 'green',
text = "m"
)
mod <- function(input, output, session, pow_id, prox){
observeEvent(pow_id(),{
if(pow_id() != 0){
pow_id <- readOGR("../geospatial_files/ind", layer = "plants")
pow_iddf <- as.data.frame(pow_id)
prox %>%
addAwesomeMarkers(lng=pow_iddf$coords.x1, lat=pow_iddf$coords.x2, group = "pow_idg", icon=icons_pow,
label = paste(pow_iddf$Name,pow_iddf$Power_type,sep = ", "))
}
else {prox %>% clearGroup("pow_idg") %>% removeControl(layerId="pow_idc")
}
}
)
}
app.R(更新):
...
source("infras.R")
...
server <- function(input, output, session) {
...
proxy <- leafletProxy("map")
callModule(mod, "mod", reactive(input$pow_id), proxy)
})
...
}
您需要将 input
对象包装到 reactive
中,并将其用作模块的 input 参数。另一个输入参数是您的传单代理。在模块内,您可以使用 observe
更改您的代理,然后立即更新:
library(shiny)
library(leaflet)
library(RColorBrewer)
# The module containing the observer. Input is the reactive handle of legend input and the proxy
mod <- function(input, output, session, legend, prox){
observe({
prox %>% clearControls()
if (legend()) {
prox %>% addLegend(position = "bottomright",
pal = colorNumeric("Blues", quakes$mag), values = ~mag
)
}
})
}
ui <- bootstrapPage(
checkboxInput("legend", "Show legend", TRUE),
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%")
)
server <- function(input, output, session) {
output$map <- renderLeaflet({
pal <- colorNumeric("Blues", quakes$mag)
leaflet(quakes) %>% addTiles() %>%
addCircles(radius = ~10^mag/10, weight = 1, color = "#777777",
fillColor = ~pal(mag), fillOpacity = 0.7, popup = ~paste(mag)) %>%
fitBounds(~min(long), ~min(lat), ~max(long), ~max(lat))
})
# This is the handle for map
proxy <- leafletProxy("map", data = quakes)
callModule(mod, "mod", reactive(input$legend), proxy)
}
shinyApp(ui, server)