r - 在 Shiny 应用程序中创建动态选项卡集会在 ggploty 上出现错误

标签 r ggplot2 plotly shiny

我在使用 Shiny 应用程序时遇到问题,但我不明白。我认为这是响应式(Reactive)对象的概念问题,但我不确定。

应用程序使用 uiOutput 根据数据集的列名称创建一个选项卡。然后我在观察中动态创建相应的plotlyOutput。

问题是,当我更改数据集时,它们的列也会更改名称,并且应用程序似乎会记住最后一个入口,并尝试使用不再存在的数据来渲染对象。

结果是一个像这样的警告:

Warning: Error in UseMethod: no applicable method for 'ggplotly' applied to an object of class "NULL" Stack trace (innermost first): 79: ggplotly 78: func 77: origRenderFunc 76: output$tabPlot_a1 1: runApp

我创建了一个 Shiny 应用程序来重现错误,只需打开它,转到选项卡 2,然后将“前缀”更改为“b”,例如。

选项卡发生变化,但会发出警告。

有任何关于正在发生的事情的提示吗?

代码:

library("shiny")
library("shinydashboard")
library("plotly")
library("ggplot2")

shinyApp(
  ui=shinyUI(dashboardPage(skin = "blue",
                           dashboardHeader(title = "Dashboard"),
                           dashboardSidebar(
                             textInput("prefix", label = "Columns prefix", value = "a")
                           ),
                           dashboardBody(
                             tabBox(
                               tabPanel("Tab 1", "This is tab number 1", tableOutput("tabData")),
                               tabPanel("Tab 2", "This is tab number 2", uiOutput("tabPlot"))
                             )
                           )
  ))
  ,
  server=shinyServer(function(input, output) {

    create_data <- reactive({
      x<-seq(-2,2,length.out=100)
      y1<-dnorm(x)
      y2<-dunif(x)
      y3<-dexp(x,2)
      y4<-dbeta(x,1,2)
      data<-data.frame(x,y1,y2,y3,y4)
      names(data)<-c("x",paste(input$prefix,1:4,sep=""))
      data
    })

    output$tabData<-renderTable({
      data<-create_data()
      data
    })

    output$tabPlot = renderUI({
      data <- create_data()
      tabnames<-names(data)[-1]
      do.call(tabsetPanel,
              lapply(tabnames,function(s){
                call("tabPanel",s,call('plotlyOutput',outputId=paste0("tabPlot_",s)))
              })
      )
    })

    observe({
      data <- create_data()
      tabnames<-names(data)[-1]
      lapply(tabnames, function(s){output[[paste0("tabPlot_",as.character(s))]] <- renderPlotly({
        data <- create_data()
        if (as.character(s) %in% names(data)){
          data.plot<-data[c("x",as.character(s))]
          p <- plotthis(data.plot)
          z <- ggplotly(p)          
        }else{
          z<-NULL
        }
        z
      })})
    })

    plotthis<-function(data){
      names(data)<-c("x","y")
      p<-ggplot(data=data,aes(x=x,y=y))+
        geom_line()
      p
    }

  })
)

最佳答案

似乎旧的输出节点之一(使用以前的名称)仍在激活,并且您内置的防护装置没有提供帮助,尽管看起来应该有帮助。我尝试了几种方法来修复它,例如将输出节点的名称固定为不更改,或者更改为以数字方式从 data 中选择列,但最终更简单的方法修复了它 - 隔离一个create_data() 语句。这会抑制不需要的输出节点激活。

这是该observe的代码 - 当我添加isolate时,我没有收到ggplotly NULL警告。请注意,只需更改一行:

observe({
  data <- create_data()
  tabnames<-names(data)[-1]
  lapply(tabnames,function(s){output[[paste0("tabPlot_",as.character(s))]]<-renderPlotly({
    data <- isolate(create_data())
    if (as.character(s) %in% names(data)){
      data.plot<-data[c("x",as.character(s))]
      p <- plotthis(data.plot)
      z <- ggplotly(p)          
    }else{
      z<-NULL
    }
    z
  })
})

顺便说一句,我从这篇文章中学到了很多东西,我不知道 observe 可以生成这样的输出节点。但我确实想知道您是否太聪明了,像这样动态重命名数据列和输出节点。你为什么要这么做?

关于r - 在 Shiny 应用程序中创建动态选项卡集会在 ggploty 上出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43560058/

相关文章:

r - 在 R 中使用 "personalised"顺序对向量进行排序

r - geom_raster 没有颜色渐变

python - 使用 Plotly Dash 进行服务器端缓存

Plotly Express,如何使用for_each_trace

javascript - 使用 Google Apps 脚本的 Plotly API

r - 在循环中使用 bnlearn 函数 "cpquery"

r - 从 CRAN 安装 R 包不包括 Bioconductor 包

r - 将所有可能的对组合在 R 中的一个数据框中

r - 使用函数向 ggplot 添加多个图层

r - ggplot 箱线图中的连接点