如何通过初始Shiny应用向已部署Shiny应用传递数据与参数?
实现Shiny应用间的数据与参数传递
需求说明
现有两个Shiny应用:
- 初始应用:支持用户上传Excel/CSV文件,展示文件列名供选择,并提供已部署应用的访问链接
- 已部署应用:默认使用
iris数据集与固定列Petal.Length生成散点图
需要实现:将初始应用中用户上传的数据、选中的列名,传递给已部署应用,替换默认的数据集与列参数。
解决方案:使用pins包实现共享数据
pins包可将数据存储到共享板(如RStudio Connect、本地文件夹等),让两个应用通过读写pin实现数据交互,以下是具体实现步骤:
1. 配置共享板
- 若使用RStudio Connect:确保两个应用关联到同一Connect服务器,使用
board_connect()连接 - 若本地测试:使用
board_folder()创建本地共享文件夹,方便调试
2. 修改初始应用代码
修复文件读取逻辑,将上传的数据与选中列名打包成list写入共享pin:
# Install and load necessary packages library(shiny) library(pins) library(readxl) # Define the UI ui <- fluidPage( titlePanel("上传数据并选择列"), column(3, fileInput("file1", "上传文件", multiple = FALSE, accept = c(".csv", ".xlsx", ".xls"))), uiOutput("select_col"), uiOutput("deployed_link") ) # Define the server server <- function(input, output, session) { # 读取上传的文件 uploaded_data <- reactive({ req(input$file1) ext <- tools::file_ext(input$file1$name) switch(ext, csv = read.csv(input$file1$datapath), xlsx = read_excel(input$file1$datapath), xls = read_excel(input$file1$datapath), stop("仅支持CSV/Excel文件") ) }) # 生成列选择框 output$select_col <- renderUI({ req(uploaded_data()) selectInput("sel_col", "选择Y轴列", choices = colnames(uploaded_data()), selected = colnames(uploaded_data())[1], multiple = FALSE) }) # 生成已部署应用链接 output$deployed_link <- renderUI({ req(uploaded_data(), input$sel_col) tagList("访问可视化应用:", a("点击进入", href = "https://deniz4shinyml.shinyapps.io/iris/")) }) # 将数据与选中列写入共享pin observe({ req(uploaded_data(), input$sel_col) # 配置共享板 - 本地测试用board_folder,部署时替换为board_connect() # board <- board_folder("shared_data") board <- board_connect() # 打包数据与参数 shared_content <- list( data = uploaded_data(), y_col = input$sel_col ) # 写入pin,设置overwrite = TRUE覆盖旧数据 board %>% pin_write(shared_content, name = "shiny_shared_data", type = "rds", overwrite = TRUE) }) } # Run the app shinyApp(ui, server)
3. 修改已部署应用代码
从共享pin中读取数据与列参数,替换默认值:
# Load required libraries library(shiny) library(ggplot2) library(pins) # 配置共享板(与初始应用一致) # board <- board_folder("shared_data") board <- board_connect() # 读取共享的内容,若读取失败则使用默认值 tryCatch({ shared_content <- pin_read(board, name = "shiny_shared_data") data <- shared_content$data y <- shared_content$y_col }, error = function(e) { # fallback到默认数据 data <- iris y <- "Petal.Length" }) # Define the UI for the Shiny app ui <- fluidPage( titlePanel("数据散点图"), sidebarLayout( sidebarPanel( p("当前使用的Y轴列:", strong(y)) ), mainPanel( plotOutput("scatterplot") ) ) ) # Define the server logic for the Shiny app server <- function(input, output) { output$scatterplot <- renderPlot({ ggplot(data, aes(x = Sepal.Length, y = .data[[y]])) + geom_point(size = 2, alpha = 0.7) + labs(y = y) + theme_minimal() }) } # Run the Shiny app shinyApp(ui, server)
关键说明
- pin名称一致性:两个应用必须使用相同的pin名称(此处为
shiny_shared_data)才能正确读写 - 覆盖旧数据:设置
overwrite = TRUE确保每次上传新数据或切换列时,已部署应用能获取最新内容 - 异常处理:已部署应用中加入
tryCatch,避免因pin读取失败导致应用崩溃,自动 fallback到默认数据 - 本地测试:使用
board_folder("shared_data")时,需确保两个应用都能访问该文件夹路径
内容的提问来源于stack exchange,提问作者firmo23
相关产品推荐
相关产品推荐

