Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to generate output for multi-plots within a loop in shiny app?

Tags:

r

shiny

very simple question: I want several barplots in output,

for example: I have a dataset: data and a list of customer: cname

shinyServer(function(input, output){
     for(name in cname){
        output[[name]] <- renderPlot({
        bp<-barplot(data[data$customer==name,1])
        })
     }
}

But it doesn't work, it seems the loop is not fully executed, need someone's help here.

like image 965
yabchexu Avatar asked Sep 02 '25 01:09

yabchexu


1 Answers

So the problem you seem to be running into is related to delayed evaluation. The commands in renderPlot() are not executed immediately. They are captured and run when the plot is ready to be drawn. The problem is that the value of name is changing each iteration. By the time the plots are drawn (which is long after the for loop has completed), the name variable only has the last value it had in the loop.

The easiest workaround would probably be to switch from a for loop to using Map. Since Map calls functions, those functions create closures which capture the current value of name for each iteration. Try this

# sample data
set.seed(15)
cname <- letters[1:3]
data <- data.frame(
    vals = rpois(10*length(cname),15),
    customer = rep(cname,each=10)
)

runApp(list(server=
shinyServer(function(input, output){
     Map(function(name) {
           output[[name]] <- renderPlot({
           barplot(data[data$customer==name,1])
        })
        },
        cname)
})
,ui=
shinyUI(fluidPage(
    plotOutput("a"),
    plotOutput("b"),
    plotOutput("c")
))
))
like image 64
MrFlick Avatar answered Sep 05 '25 16:09

MrFlick