You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R Shiny仪表盘部署异常:本地正常部署后无法加载PNG文件

问题分析与解决方案

问题核心原因

你的Shiny应用本地单文件运行正常,但拆分部署后下拉菜单无选项、无法显示图片,本质是本地文件路径与部署环境不兼容,具体有三个关键问题:

  • 硬编码本地绝对路径:部署后的服务器(如shinyapps.io)没有你电脑C盘的C:/Users/username/Dropbox/...路径,根本找不到图片文件。
  • UI阶段提前读取本地目录:ui.R在部署时会在服务器端执行,服务器没有你的本地Annual文件夹,导致country_names为空,第一个下拉菜单直接无选项。
  • 全局变量滥用:server里用<<-给previous_country全局赋值,部署环境下会引发变量作用域问题,且这个逻辑完全没必要。

修复方案

1. 调整应用文件结构

把所有PNG图片文件夹(Annual、Quarterly)复制到Shiny应用的根目录下,结构如下:

你的应用文件夹/
├─ ui.R
├─ server.R
└─ Plots/
   ├─ Annual/
   └─ Quarterly/

2. 修改ui.R代码

移除UI阶段的本地目录读取逻辑,改用server端动态生成下拉选项:

library(shiny)
library(png)
library(dplyr)
library(ggplot2)
library(rsconnect)

ui <- fluidPage(
  column(width = 3, 
         uiOutput("country_selector"),  # 改为动态生成国家选项
         selectInput("freq", "Select Frequency", choices = c("Annual", "Quarterly")),
         selectInput("folder", "Select Plot Type", choices = c("Difference from base", "Level")),
         uiOutput("file_selector")
  ),
  column(width = 9, 
         imageOutput(outputId = "plot", height = 600, width = 800)
  )
)

3. 修改server.R代码

改用相对路径访问文件,将目录读取逻辑移到reactive环境中,用reactiveVal跟踪变量避免全局赋值:

library(shiny)
library(png)
library(dplyr)
library(ggplot2)
library(rsconnect)
library(grid)

server <- function(input, output, session) {
  # 用reactiveVal跟踪之前选中的国家,替代全局变量
  previous_country <- reactiveVal("")
  
  # 动态生成国家下拉选项
  output$country_selector <- renderUI({
    annual_dir <- file.path("Plots", "Annual")
    country_names <- list.files(annual_dir, recursive = FALSE)
    selectInput("country", "Select Country", choices = country_names)
  })
  
  file_list <- reactive({
    # 更新跟踪的国家
    if (input$country != previous_country()) {
      previous_country(input$country)
      message("Updating country...")
    }
    
    # 用相对路径构建目标路径
    chosen_path <- file.path("Plots", input$freq, input$country, input$folder)
    # 路径不存在时返回空列表,避免报错
    if (!dir.exists(chosen_path)) {
      return(c())
    }
    png_files <- list.files(chosen_path, pattern = "\\.png$")
    png_files <- png_files[!grepl("^(asl|asd|ql|qd)", png_files)]
    png_files <- gsub("\\.png$", "", png_files)
    return(png_files)
  })
  
  output$file_selector <- renderUI({
    selectInput(inputId = "file", label = "Select a file", 
                choices = file_list())
  })
  
  output$plot <- renderPlot({
    req(input$file)  # 确保文件被选中后再执行
    chosen_file <- file.path("Plots", input$freq, input$country, input$folder, paste0(input$file, ".png"))
    
    # 文件不存在时显示提示文本
    if (!file.exists(chosen_file)) {
      return(ggplot() + annotate("text", x=1, y=1, label="文件不存在"))
    }
    
    img <- readPNG(chosen_file)
    grid.raster(img)
  })
}

4. 部署注意事项

使用deployApp()部署时,应用目录下的Plots文件夹会被自动上传,无需额外配置。


内容的提问来源于stack exchange,提问作者Carl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:53:08