根据ggplots列表中的图表数量创建一些renderPlot函数?

时间:2015-02-17 02:52:10

标签: r ggplot2 shiny

根据ggplots列表中的图表数量,有什么办法可以动态创建多个renderPlot函数吗?

我有一个Shiny应用程序,而不是使用稳定的UI,而不是使用renderUI,我依靠用户提供的配置文件来告诉Shiny要显示多少个图。配置文件还提供数据,几乎可以帮助完成大部分繁重工作。

经过多次战斗,我大部分都在那里。使用方便的配置文件,我可以构建正确的UI,并生成正确数量的ggplots。 ggplots位于列表中,创造性地命名为list_of_ggplots

但是现在,我已经有了一个ggplots列表,我需要允许它们像这样使用它们来绘制:

  output$plot1 <- renderPlot({
  print(list_of_ggplots[[1]])
})

但现在我有一个存在主义危机 - 我不能这样做,因为用户提供的配置文件告诉我我有多少个情节。我不能像通常在Shiny中那样硬编码renderPlot调用,因为所需的这些函数的数量在配置文件中定义。

鉴于我的ggplots列表,我需要一些方法来生成renderPlot次调用。

有没有人这样做或有任何想法?非常感谢。

这是我的代码:

SERVER.R:

library(shiny)
library(ggplot2)

# 3 simple plots of different colors -- used here instead of all the complicated stuff
# where someone uses the config file that specified 3 plots, with data, etc.

ggplot_names <- c("p1", "p2", "p3")
ggplot_colors <- c("red", "blue", "green")
list_of_ggplots <- list()
j = 1
for (i in ggplot_names){
  i <- ggplot(data.frame(x = c(-3, 3)))         
  i <- i + aes(x)
  i <- i + stat_function(fun = dnorm, colour=ggplot_colors[[j]])
  list_of_ggplots[[j]] <- i
  j <- j+ 1
}

## here's the problem -- the user specified 3 plots. 
## I can't hardcode the following shinyServer functions!!!
## What if tomorrow, the user specifies 2 plots instead?
shinyServer(function(input, output) { 

  output$plot1 <- renderPlot({
  print(list_of_ggplots[[1]])
})

  output$plot2 <- renderPlot({
  print(list_of_ggplots[[2]])
})

  output$plot3 <- renderPlot({
  print(list_of_ggplots[[3]])
})
})

UI.R

## this top part is actually sourced from the config file
## since Shiny needs to know how many tabPages to use,
## names for the tabs, etc

number_of_tabPages <- 3
tab_names <- c("", "Tab1", "Tab2", "Tab3")
tabs<-list()
tabs[[1]]=""
for (i in 2:(number_of_tabPages+1)){
  tabs[[i]]=tabPanel(tab_names[i],plotOutput(paste0("plot",i-1)))}

## Here's the familiar UI part
shinyUI(fluidRow(

        column(12,
               "", 
               do.call(navbarPage,tabs)
              ) 
                )
      )

1 个答案:

答案 0 :(得分:1)

您可以使用此解决方案(我仅修改了脚本的shinyServer部分,因此我不会在此处列出重复代码):

 shinyServer(function(input, output) {

 observe(
     lapply(seq(3),function(i) output[[paste0("plot",i)]] <- renderPlot(list_of_ggplots[[i]]))
 )

 })

当然,您可以用变量替换3