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

Shiny处理reactive dataframe报invalid (NULL)赋值错误

报错原因

你遇到的invalid (NULL) left side of assignment报错由两个问题直接引发:

  • Shiny中通过reactive()生成的响应式对象是只读的,每次调用reactiveDf()只会返回计算好的结果副本,你不能直接对这个返回的临时副本做赋值操作,这类赋值本身不符合Shiny响应式规则。
  • 代码中reactiveDf()[i]="Insignificant"的写法是对数据框的第i列做整列赋值,而非对行赋值;当循环的i值超过数据框总列数时,索引到的位置为NULL,就触发了左值无效的报错。
修复方法
  1. 在绘图逻辑中,先把reactiveDf()的返回值存为普通的非响应式数据框变量,所有修改操作都针对这个普通变量执行,不要直接改reactive的返回结果。
  2. 修正数据框索引逻辑,给行赋值时明确指定行列位置,避免单索引默认取列的问题。
  3. 补全绘图的返回逻辑,生成ggplot对象后要转为plotly并返回,否则图表无法渲染。
修正后完整代码
library(shiny)
library(shinydashboard)
library(plotly)
library(tidyr)
library(dplyr)
library(DT)
BRAND<-c("CHOKIS","CHOKIS","CHOKIS","CHOKIS","CHOKIS","CHOKIS","LARA CHOCO CHIPS","LARA CHOCO CHIPS","LARA CHOCO CHIPS")
BRAND_COLOR<-c("#8050f0","#8050f0","#8050f0","#8050f0","#8050f0","#8050f0","#f050c0","#f050c0","#f050c0")

SellOut.x<-c(23,34,56,77,78,34,34,64,76)
SellOut.y<-c(43,54,76,78,87,98,76,76,56)
GrossProfit.x1<-c(23,34,56,75,78,34,34,64,76)
GrossProfit.y1<-c(33,54,76,76,87,98,76,76,56)
GrossSales.x2<-c(53,34,56,77,78,34,34,84,76)
GrossSales.y2<-c(63,54,76,78,87,98,76,76,86)
r<-c(58,46,76,76,54,21,69,98,98)

graph1.data<-data.frame(BRAND,BRAND_COLOR,r)

# 待合并的指标数据框
df6 <- data.frame(SellOut.x, SellOut.y, GrossProfit.x1, GrossProfit.y1, GrossSales.x2, GrossSales.y2) 

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    selectInput("metric","Metric",c('Gross Sales','Gross Profit','Sell Out'),multiple = T,selected = "Sell Out")
  ),
  dashboardBody(
    DTOutput("df"),
    plotlyOutput("plot")
  )
)

server <- function(input, output) {
  
  choices <- reactive({
    c3 <- gsub(" ", "", input$metric) # 移除指标名空格做匹配
    return(c3)
  })
  
  reactiveDf <- reactive({
    if(length(choices()) > 0){
      # 匹配选中指标对应的列
      g1 <- apply(sapply(X = choices(), FUN = grepl, colnames(df6)), MARGIN =  1, FUN = any)
      
      addedDf <- df6[, g1] # 提取要添加的指标列
      colnames(addedDf) <- c("x", "y", "x1", "y1", "x2", "y2")[1:ncol(addedDf)] # 统一列名
      
      combinedDf <- cbind(graph1.data, addedDf) # 合并基础数据和指标数据
      combinedDf$label<-paste(combinedDf$BRAND,"-",input$metric)
      return(combinedDf)
    }else{
      graph1.data$label<-paste(graph1.data$BRAND,"-",input$metric)
      return(graph1.data) 
    }
  })
  
  output$df<-renderDT({
    reactiveDf()
  })
  
  output$plot<-renderPlotly({
    req(reactiveDf(), length(input$metric)>=1)
    metric<-input$metric
    # 先把响应式数据转成普通变量再修改
    plot_df <- reactiveDf()
    brand.colors <- plot_df$BRAND_COLOR
    names(brand.colors) <- plot_df$BRAND
    data<-unique(plot_df$BRAND)
    ind=which(names(brand.colors) %in% data)
    
    if(length(metric) == 1) {
      for ( i in 1:nrow(plot_df))
      {
        plot_df$BRAND[i]=paste(plot_df$BRAND[i],metric)
      }
      if (metric!="Sell Out")
      {
        for (i in ind)
        {
          brand.colors[i]="gray"
          # 明确指定行、列索引,避免维度索引错误
          plot_df[i, "BRAND"]="Insignificant"
        }
      }
      
      names(brand.colors) <- plot_df$BRAND
      
      p <- plot_df %>%
        ggplot2::ggplot(aes(x, y, color = BRAND, group=BRAND))
      p <- p + 
        ggplot2::geom_line() + 
        suppressWarnings(ggplot2::geom_point(aes(size = r), show.legend = TRUE)) +
        ggplot2::scale_color_manual(values = brand.colors)
      # 转成plotly对象返回
      ggplotly(p)
    }
  })
}

shinyApp(ui, server)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:45:47