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

R Shiny弹窗无法生成K线图的问题解决请求

解决Shiny仪表盘K线图弹窗报错及绘图位置问题

问题原因

  1. 图表显示位置错误:quantmod::candleChart默认直接输出到RStudio的绘图设备,不会返回可被Shiny renderPlot识别的对象,导致图表无法渲染到弹窗中。
  2. "subscript out of bounds"错误:使用read.table处理单股票字符串时会生成异常维度的数据框,索引操作触发维度错误;同时弹窗内直接传递无效的绘图对象给renderPlot,导致渲染失败。

解决方案

  1. 用strsplit替代read.table处理股票列表,生成稳定的字符向量。
  2. 将candleChart调用直接放在renderPlot内部,利用Shiny的绘图上下文完成弹窗内的图表渲染。
  3. 修正动态UI和事件绑定的命名空间逻辑,避免索引错误。

修改后的完整代码

library(quantmod)
library(shiny)

# 获取并整理股票数据
getSymbols(c("AAPL", "MSFT", "META", "ORCL", "TSLA", "GOOG"), 
           from = "2020/01/01", to = Sys.Date(), periodicity = "daily")

process_stock <- function(symbol) {
  df <- as.data.frame(get(symbol))
  df$DATE <- index(get(symbol))
  rownames(df) <- NULL
  names(df) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
  df$SYMBOL <- symbol
  df[, c('SYMBOL','DATE','OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED')]
}

df_all <- do.call(rbind, lapply(c("AAPL", "MSFT", "META", "ORCL", "TSLA", "GOOG"), process_stock))

# 日期-股票映射数据
df_rep_date <- data.frame(
  RunDate = as.Date(c("2020-01-06", "2021-01-04", "2022-01-04")),
  ListStocks = c('AAPL,GOOG,TSLA', 'ORCL', 'META,MSFT'),
  stringsAsFactors = FALSE
)
v_lst_sel_dates <- df_rep_date$RunDate

# 生成股票表格数据
func_1symb_tab <- function(p_symb){
  df_tmp_hist_dat <- df_all[df_all$SYMBOL == p_symb,c("DATE" ,"OPEN","HIGH","LOW" ,"CLOSE","VOLUME" )]
  df_tmp_hist_dat[1:5,]
}

# UI模块
simpUI <- function(id) {
  tagList(
    selectInput(NS(id, 'RunDate'), "Run Date", v_lst_sel_dates),
    textOutput(NS(id,'date_output')),
    textOutput(NS(id,'lst_symb_output')),
    uiOutput(NS(id,"stock_cards"))
  )
}

# Server模块
simpServer <- function(id) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    
    output$date_output <- renderText(input$RunDate)
    
    # 获取当前选中日期对应的股票列表
    v_lst_symbol <- reactive({
      strsplit(df_rep_date[df_rep_date$RunDate == input$RunDate,]$ListStocks, ",")[[1]]
    })
    
    output$lst_symb_output <- renderText(paste(v_lst_symbol(), collapse = ", "))
    
    # 动态生成股票卡片(名称+表格+按钮)
    output$stock_cards <- renderUI({
      lapply(v_lst_symbol(), function(v_symb){
        fluidRow(
          h4(v_symb),
          tableOutput(ns(paste0(v_symb, '_table'))),
          actionButton(ns(paste0(v_symb, '_cndl_chart')), "查看K线图")
        )
      })
    })
    
    # 为每个股票生成表格输出
    observeEvent(v_lst_symbol(), {
      lapply(v_lst_symbol(), function(v_symb){
        output[[paste0(v_symb, '_table')]] <- renderTable(func_1symb_tab(v_symb))
      })
    })
    
    # 为每个按钮绑定弹窗事件
    observeEvent(v_lst_symbol(), {
      lapply(v_lst_symbol(), function(v_symb){
        btn_id <- paste0(v_symb, '_cndl_chart')
        observeEvent(input[[btn_id]], {
          showModal(modalDialog(
            title = paste(v_symb, "K线图"),
            size = "l",
            renderPlot({
              # 直接在renderPlot内生成K线图
              df_tmp_hist_dat <- df_all[df_all$SYMBOL == v_symb,c("DATE" ,"OPEN","HIGH","LOW" ,"CLOSE","VOLUME" )]
              v_df_dly_dat_xts <- xts(df_tmp_hist_dat[, -1], order.by = df_tmp_hist_dat[, 1])
              candleChart(v_df_dly_dat_xts, 
                          name = v_symb, 
                          type = "auto", 
                          up.col = "green", 
                          dn.col = "red",
                          theme = "white",
                          TA = "addVo();addSMA(n=1, col='black');addSMA(n=7, col='gold');addSMA(n=14, col='brown');addMACD();addBBands();addRSI();addOBV();")
            })
          ))
        })
      })
    })
  })
}

# 主程序
ui <- fluidPage(fluidRow(simpUI("par1")))
server <- function(input, output, session) {
  simpServer("par1")
}
shinyApp(ui = ui, server = server)

关键修改点

  • 新增process_stock函数简化股票数据整理逻辑,减少重复代码。
  • 用strsplit处理股票列表,避免read.table带来的维度问题。
  • 将candleChart直接放在renderPlot内部执行,利用Shiny的绘图上下文将图表渲染到弹窗。
  • 拆分动态UI和事件绑定逻辑,代码结构更清晰,避免命名空间冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:24:44