Shiny应用问题:如何根据输入值切换绘图数据及空间对象?
问题解决:Shiny应用切换数据集时绘图报错找不到空间对象
错误原因分析
- 绘图函数作用域问题:
map_gi函数内部直接调用l1和l2,但这两个变量是Server中定义的reactive对象,不在函数的作用域范围内,导致调用时找不到对象。 - 空间对象列表定义错误:
dlistsp中用c(l1,l2)会将空间对象合并为向量,无法通过$l1、$l2正确访问,应该用list()创建命名列表。 - 未传递空间对象给绘图函数:调用
map_gi时没有传入当前数据集对应的l1()和l2()reactive对象。
修正步骤及完整代码
1. 修正空间对象列表定义
将c(l1,l2)改为list(l1 = 对应多边形对象, l2 = 对应点对象),确保每个数据集的空间对象是命名列表(替换示例中的lad_l1/lad_l2/qp_l1/qp_l2为实际空间对象):
dlistsp <- list( lad_sp = list(l1 = lad_l1, l2 = lad_l2), qp_sp = list(l1 = qp_l1, l2 = qp_l2) )
2. 修改绘图函数,添加空间对象参数
让map_gi接收l1和l2作为参数,避免依赖全局变量:
map_gi <- function(loc, title, l1, l2) { pal <- colorRampPalette(c("steelblue", "white", "tomato2"), bias = 1) collist <- pal(10) class <- classIntervals(loc, 8, style = "fixed", fixedBreaks = c(min(loc), -2.33, -1.96, -1.28, 0, 1.28, 1.96, 2.33, max(loc))) color <- findColours(class, collist) par(mar = c(0, 0, 0, 0)) plot(l1, lwd = 0.4, col="grey80", border="white", main=title) plot(l2, pch=21, cex=.9, col="black", bg=color, add=T) }
3. 修正Server中的绘图调用
在renderPlot中传递l1()和l2()给map_gi:
server <- function(input, output, session) { choice <- reactive({ dlist[[input$dataset]] }) observeEvent(input$dataset, { req(choice()) vars <- names(choice()) updateSelectInput(session,"var",choices = vars) }) l1 <- reactive({ if (input$dataset == "LAD") { dlistsp$lad_sp$l1 } else if (input$dataset =="QP") { dlistsp$qp_sp$l1 } }) l2 <- reactive({ if (input$dataset == "LAD") { dlistsp$lad_sp$l2 } else if (input$dataset =="QP") { dlistsp$qp_sp$l2 } }) output$plot <- renderPlot({ req(choice(), input$var, l1(), l2()) # 传递reactive返回的空间对象给绘图函数 map_gi(choice()[, input$var], input$var, l1(), l2()) }) output$table <- renderDT({choice()}) }
4. 保留原UI代码
UI部分无需修改,保持原有逻辑即可:
ui <- fluidPage( titlePanel(p("Autocorrelation",style = "color:#3474A7")), sidebarLayout( sidebarPanel( radioButtons(inputId = "dataset", "Choose a dataset:",c("LAD","QP")), selectInput(inputId = "var", "Select a variable:",choices = NULL) ), mainPanel( plotOutput("plot"), DTOutput(outputId = "table") ) ) )
额外提示
- 确保
dlist中的数据框gi_lad、gi_qp与对应的空间对象l1、l2的行/点数量匹配,避免绘图时颜色映射出错。 - 可以在
req()中添加更具体的检查,比如req(nrow(choice()) == length(l2())),确保数据和空间对象对应。
内容的提问来源于stack exchange,提问作者eazyezy
相关产品推荐
相关产品推荐

