R Shiny:无法在响应式消费者之外访问响应式值。

9
我正在尝试构建一个Shiny应用程序,对栅格文件进行一些修改,绘制它并提供下载(修改后的)栅格文件的选项。我遇到了以下错误:
Listening on http://127.0.0.1:3371
Warning: Error in : Can't access reactive value 'divider' outside of reactive consumer.
ℹ Do you need to wrap inside reactive() or observer()?
  53: <Anonymous>
Error : Can't access reactive value 'divider' outside of reactive consumer.
ℹ Do you need to wrap inside reactive() or observer()?

我做错了什么?我在RStudio社区找到了一个相关问题this,但它没有帮助我。请问有人可以帮我理解吗?

最小工作示例

ui.R

shinyUI(fluidPage(

    # Application title
    titlePanel("Urban-Rural Raster Population"),

    # Sidebar 
    sidebarLayout(
        sidebarPanel(
            sliderInput("divider",
                        "Divider number:",
                        min = 1,
                        max = 29,
                        value = 7),
            downloadButton("download1", "Download Rural Raster"),
            downloadButton("download2", "Download Urban Raster")
        ),

        # plots
        mainPanel(
            plotOutput("plot1"),
            plotOutput("plot2")
        )
    )
))

server.R

# Loading all external data - so that its done only once
rast_pop = read_stars("ind_ppp_2020_1km_Aggregated_UNadj.tif", proxy = F)
urca_raster = read_stars("URCA.tif", proxy = T)
names(urca_raster) = "urca"

# Finding rasters for India's boundaries
ind_shp = st_as_sf(getData('GADM', country ='IND', level = 0)) # for country
ind_st_shp = st_as_sf(getData('GADM', country ='IND', level = 1))  #for states boundary
ind_dis_shp = st_as_sf(getData('GADM', country = 'IND', level = 2)) # for district boundary

# cropping India from raster
ind_urca = st_crop(urca_raster, ind_shp)


# Define server logic 
shinyServer(function(input, output) {

    div_ru = input$divider
    
    # dividing on the basis of rural and urban
    ind_rur = ind_urca > div_ru
    ind_urb = ind_urca <= div_ru
    ind_rur_star = st_as_stars(ind_rur)
    ind_urb_star = st_as_stars(ind_urb)
    
    output$plot1 = renderPlot({
        plot(ind_rur_star)
        })
    
    output$plot2 = renderPlot({
        plot(ind_urb_star)
    })
    
    output$download1 = downloadHandler(
        filename = function() {
            paste0("rural_raster_", input$divider, ".tif")
            },
        content = function(file) {
            write_stars(ind_rur_star, file, layer = 1)
        }
    )
    output$download2 = downloadHandler(
        filename = function() {
            paste0("urban_raster_", input$divider, ".tif")
        },
        content = function(file) {
            write_stars(ind_urb_star, file, layer = 1)
        }
    )
})
1个回答

6
问题在于,正如错误所示的那样,divider是响应式的,但您正在响应式环境之外使用它。例如,像ind_rur这样的变量需要在每次divider更改时重新计算,但在您的代码中,它们仅计算一次。
尝试在server函数中尝试以下内容:
shinyServer(function(input, output) {

    div_ru <- reactive({
       input$divider
    })
    
    # dividing on the basis of rural and urban
    ind_rur <- reactive({ind_urca > div_ru()})
    ind_urb <- reactive({ind_urca <= div_ru()})
    ind_rur_star <- reactive({st_as_stars(ind_rur())})
    ind_urb_star <- reactive({st_as_stars(ind_urb())})
    
    output$plot1 = renderPlot({
        plot(ind_rur_star())
        })
    
    output$plot2 = renderPlot({
        plot(ind_urb_star())
    })
    
    output$download1 = downloadHandler(
        filename = function() {
            paste0("rural_raster_", div_ru(), ".tif")
            },
        content = function(file) {
            write_stars(ind_rur_star(), file, layer = 1)
        }
    )
    output$download2 = downloadHandler(
        filename = function() {
            paste0("urban_raster_", div_ru(), ".tif")
        },
        content = function(file) {
            write_stars(ind_urb_star(), file, layer = 1)
        }
    )
})

谢谢!我曾经认为 shinyServer 中的所有代码都会自动重新计算。澄清一下:服务器内涉及输入的任何计算默认都是反应式的吗?这是否意味着服务器中所有使用输入的地方都应该是反应式的? - Harshvardhan
1
是的,所有传递到服务器的输入都是响应式的。服务器中的某些环境默认情况下是响应式的,例如renderPlot()。因此,您可以在renderPlot()内部使用input$input1。但是您特定的问题是,在任何响应式环境之外,在server中有类似input$input1的内容。 - VitaminB16
这里到底是什么解决方案? - Ben
1
ind_rur_star = st_as_stars(ind_rur) 变成 ind_rur_star <- reactive({st_as_stars(ind_rur())}) 等等,每当输入变化时需要重新计算的所有其他变量,也应该相似地修改。而且,每次调用 ind_rur_star 时,它都应该写成 ind_rur_star() - VitaminB16

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接