我在使用 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/