Dynamic number of plots in Shiny - r

I want to display a dynamic number of plots in Shiny according to some data rows that the user can pick from. I achieved this, however I keep getting the same plot. The right amount of times, but always with the wrong data.
I already tried debugging, but the loops seem to work. Three plots with the plot id's 'plot1' 'plot2' 'plot3' are created. I also checked the browser inside the loop where I create the plots...the x and y values are the right ones...
Anyone have a clue what I'm doing wrong?
ui <- bootstrapPage(
navbarPage("Anpassung Lastmodell",
tabPanel("Graph",
fluidRow(width=4,
uiOutput('alphaui'),
uiOutput('graphui')
)
)
)
)
server <- function(input, output, session) {
## Output Graphs
output$alphaui <- renderUI({
# Here I usually have a manually uploaded dataset, so that's why this part is in a dynamic UI
# The user selects the columns of the data he wants in the plots
alphacat <- beaver1
paramnames <- colnames(alphacat)
graphparam <- vector("list",length(paramnames))
for (i in 1:length(paramnames)) {
graphparam[[i]] <- list(checkboxInput(paste0("graphparam",i,sep=""),paramnames[i],value=FALSE))
}
graphparam[[i+1]] <- actionButton("graph_button", "Los!",width="200px")
return(graphparam)
})
output$graphui <- renderUI({
graph <- plots()
graph
})
plots <- eventReactive(input$graph_button, {
# Selecting data to be plotted
alphacat <- beaver1
paramnames <- colnames(alphacat)
paramnames_keep <- isolate(unlist(reactiveValuesToList(input)[paste0("graphparam",1:length(paramnames),sep="")]))
paramnames <- cbind(paramnames,paramnames_keep)
paramnames <- subset(paramnames,paramnames[,"paramnames_keep"]==TRUE,"paramnames")
graph <- list()
i <- 1
for (i in 1:length(paramnames)) {
plotname <- paste("plot",i, sep="")
x <- alphacat[,paramnames[i]]
y <- alphacat$time
output[[plotname]] <- renderPlot({
plot(x,y)
})
graph[[i]] <- plotOutput(plotname,height=330,width=300)
tagList(graph)
}
return(graph)
})
}
shinyApp(ui,server)

The issue in your code as it is posted right now, is that the y variable is not definedL
x <- alphacat[,paramnames[i]]
y <- alphacat$aq1
output[[plotname]] <- renderPlot({
plot(x,y)
})
y$aq1 does not exist. Therefore, right now your plotting statement plot(x,y) is the same as plot(x). (try print(y) after the statement where you define y)

Related

Issue with showing multiple tables in a for loop in rshiny

Currently, i am trying to output multiple tables i managed to retrieve with an api call onto a dashboard page with a single uiOutput().
took some reference from this post:
R Shiny - Display multiple plots selected with checkboxGroupInput
however, while i was succesful in putting it into a list for the overall layout and output it into uioutput(), i was not able to acheive the desired results as all the tables were the same, in reality it should be different as i have already tagged a unique dataframe to each renderdatatable()
below shows the screen shot and the code. would appreciate some help here thank you!
[1]: https://i.stack.imgur.com/W0B26.png
library(httr)
library(jsonlite)
library(plyr)
library(data.table)
library(rlist)
library(shiny)
########### UI ############
ui <- fluidPage(uiOutput('datatables'))
######### SERVER ###########3
server <- function(input, output, session){
output$datatables <- renderUI({
link <- 'https://api.zapper.fi/v1/protocols/balances/supported?addresses%5B%5D=0x58bbae0159117a75225e72d941dbe35ffd99f894&api_key=96e0cc51-a62e-42ca-acee-910ea7d2a241'
test <- GET(link)
test <- fromJSON(rawToChar(test$content))
counter1 <- 0
out <- list()
df <- list()
for (i in seq(from = 1, to = length(test$network))){
network <- test$network[i]
#counter <- counter + 1
out <- list(out, h2(paste0(str_to_title(network),' Network')))
for (e in ldply(test$protocols[i], data.frame)$protocol){
link1 <- paste0(paste0('https://api.zapper.fi/v1/protocols/',e),paste0(paste0('/balances?addresses%5B%5D=0x58bbae0159117a75225e72d941dbe35ffd99f894&network=',network),'&api_key=96e0cc51-a62e-42ca-acee-910ea7d2a241'))
data <- fromJSON(rawToChar(GET(link1)$content))
wallet <- '0x58bbae0159117a75225e72d941dbe35ffd99f894'
#info <- ldply(eval(parse(text=sprintf("data$'%s'$products$assets",wallet))),data.frame)
out <- list(out, h3(paste0(str_to_title(e),' Protocol')))
counter1 <- counter1 + 1
df[[counter1]] <- ldply(eval(parse(text=sprintf("data$'%s'$products$assets",wallet))),data.frame)
out<- list(out, renderDataTable(df[[counter1]]))
}
}
return(out)
})
}
shinyApp(ui, server)
UPDATE: I ALSO TRIED TO WRAP IT IN AN OBSERVE() AND LOCAL () FOR THE DIFFERENT OUTPUTS, STILL DIDNT ACHEIVE THE DESIRED RESULTS, ALL SAME TABLES WHICH IS WRONG
I almost achieved the desired result with the following code:
library(httr)
library(jsonlite)
library(plyr)
library(data.table)
library(rlist)
library(shiny)
# added :
library(DT)
library(stringr)
########### UI ############
ui <- fluidPage(
uiOutput('datatables')
)
######### SERVER ###########
server <- function(input, output, session){
link <- 'https://api.zapper.fi/v1/protocols/balances/supported?addresses%5B%5D=0x58bbae0159117a75225e72d941dbe35ffd99f894&api_key=96e0cc51-a62e-42ca-acee-910ea7d2a241'
test <- GET(link)
test <- fromJSON(rawToChar(test$content))
output$datatables <- renderUI({
outputlist <- lapply(1:length(test$network), function(i) {
network <- test$network[i]
networkTitle <- paste0("networktitle", i)
lapply(seq_along(ldply(test$protocols[i], data.frame)$protocol), function(j) {
protocolTitle <- paste0("protocoltitle", i, j)
outputId <- paste0("network", i, "protocol", j)
tagList(
#uiOutput(networkTitle),
uiOutput(protocolTitle),
DTOutput(outputId)
)
})
})
})
lapply(1:length(test$network), function(i) {
network <- test$network[i]
my_i <- i
networkTitle <- paste0("networktitle", my_i)
#local({
# my_network <- network
# output[[networkTitle]] <- renderUI({
# tags$h2(paste0(str_to_title(my_network),' Network'))
# })
#})
lapply(seq_along(ldply(test$protocols[my_i], data.frame)$protocol), function(j) {
e <- ldply(test$protocols[my_i], data.frame)$protocol[[j]]
local({
my_network <- network
my_e <- e
my_j <- j
protocolTitle <- paste0("protocoltitle", my_i, my_j)
outputId <- paste0("network", my_i, "protocol", my_j)
link1 <- paste0(paste0('https://api.zapper.fi/v1/protocols/',my_e),paste0(paste0('/balances?addresses%5B%5D=0x58bbae0159117a75225e72d941dbe35ffd99f894&network=',my_network),'&api_key=96e0cc51-a62e-42ca-acee-910ea7d2a241'))
data <- fromJSON(rawToChar(GET(link1)$content))
wallet <- '0x58bbae0159117a75225e72d941dbe35ffd99f894'
output[[protocolTitle]] <- renderUI({
tags$h3(paste0(str_to_title(my_network),' Network - ', str_to_title(my_e),' Protocol'))
})
output[[outputId]] <- renderDT({
ldply(eval(parse(text=sprintf("data$'%s'$products$assets",wallet))),data.frame)
})
})
})
})
}
shinyApp(ui, server)
I used two nested lapply but this might work with for loops as well (using local()).
As you mentioned, we have several difficulties here:
the need to use local() to get unique IDs for each protocol title and datatable (see this)
the need to use one renderUI in the server part to generate several types of outputs dynamically (uiOutput for titles, DTOutput for datatables), all contained in a tagList(). See this and this again.
The need to use two nested for loops/lapply functions to render the shiny outputs used in the renderUI() part.
I combined the network and protocol titles because I was not able to get network titles as unique h2 titles as shown in your example figure. Duplicate output IDs were still generated for h2 titles when using the commented code. I let the commented code as reference if someone wants to try improve it.

Challenge with dynamically generated, interactive R Shiny plots (mostly functioning code)

Below is the minimum code. It works, but there is a weird problem. Here is what works:
User can select a number of plots (default is 3).
User can click in a plot and have that value represented (partly works).
Steps to reproduce the "partly works":
At launch, click in plot #3, no problem.
Click in plot #2, nothing happens.
Reduce the number of plots from 3 to 2 and then back to 3.
Click in plot #2, now it works.
Click in plot #1, nothing happens.
Reduce the number of plots from 3 to 1 and then back to 3.
Click in plot #1, now it works.
If you reload the app, and start with step 6 above, all plots are interactive as expected.
rm(list=ls())
library(shiny)
#
# Dynamic number of plots: https://stackoverflow.com/questions/26931173/shiny-r-renderplots-on-the-fly
# That can invalidate each other: https://stackoverflow.com/questions/33382525/how-to-invalidate-reactive-observer-using-code
#
ui <- (fluidPage(sidebarLayout(
sidebarPanel(
numericInput("np", "Plots:", min=0, max=10, value=3, step=1)
)
,mainPanel(
fluidRow(uiOutput("plots"))
)
)))
server <- function(input, output, session) {
val <- reactiveValues()
dum <- reactiveValues(v=0)
obs <- list()
### This is the function to break the whole data into different blocks for each page
plotInput <- reactive({
print("Reactive")
np <- input$np
for(i in 1:np) {
cx <- paste0("clk_p",i); dx <- paste0("dbl_p",i); px <- paste0("p",i)
obs[[cx]] <- observeEvent(input[[cx]], {
req(input[[cx]]); val[[px]] <- input[[cx]]$x; dum$v <- dum$v+1; print(paste("Dum",dum$v))
})
obs[[dx]] <- observeEvent(input[[dx]], {
req(input[[dx]]); val[[px]] <- NULL
})
}
return (list(np=np))
})
##### Create divs######
output$plots <- renderUI({
print("Tag plots")
pls <- list()
for(i in 1:plotInput()$np) {
pls[[i]] <- column(4,
plotOutput(paste0("p",i), height=200, width=200
,click=paste0("clk_p",i)
,dblclick=paste0("dbl_p",i))
)
}
tagList(pls)
})
observe({
print("Observe")
lapply(1:plotInput()$np, function(i){
output[[paste("p", i, sep="") ]] <- renderPlot({
print(paste("Plot",dum$v))
x <- val[[paste0("p",i)]]
x <- ifelse(is.null(x),"NA",round(x,2))
par(mar=c(2,2,2,2))
plot(x=runif(20), y=runif(20), main=i, xlim=c(0,1), ylim=c(0,1), pch=21, bg="gray", cex=1.5)
if(is.numeric(x)) abline(v=x, col="blue")
rm(x)
})
})
})
}
shinyApp(ui, server)
Here is a working version of what you're trying to do:
library(shiny)
ui <- fluidPage(
sidebarPanel(
numericInput("num", "Plots:", 3)
),
mainPanel(
uiOutput("plots")
)
)
server <- function(input, output, session) {
obs <- list()
val <- reactiveValues()
observe({
lapply(seq(input$num), function(i){
output[[paste0("plot", i) ]] <- renderPlot({
click_id <- paste0("clk_p",i);
plot(x = runif(20), y = runif(20), main=i)
if (!is.null(val[[click_id]])) {
abline(v = val[[click_id]], col = "blue")
}
})
})
})
observe({
lapply(seq(input$num), function(i){
id <- paste0("clk_p",i);
if (!is.null(obs[[id]])) {
obs[[id]]$destroy()
}
val[[id]] <- NULL
obs[[id]] <<- observeEvent(input[[id]], {
cat('clicked ', id, ' ', input[[id]]$x, '\n')
val[[id]] <- input[[id]]$x
}, ignoreInit = TRUE)
})
})
output$plots <- renderUI({
lapply(seq(input$num), function(i) {
id <- paste0("plot", i)
plotOutput(id, height=200, width=200, click=paste0("clk_p",i))
})
})
}
shinyApp(ui,server)
A few main pointers for anyone who sees this in the future:
The main issue with the original code was that all the observers were registering only for the last ID. This is a bit of an advanced concept and has to do with the way environments in R work and because they were created in a for loop. The fix for this is to use lapply() instead of a for loop to create the observers
Another issue is that obs was overwriting the observers in the list, but the previous observers still exist and can still fire, so I added logic to destroy() existing observers.
One of the most important rules in shiny is to not place side effects inside reactives (plotInput has side effects) so I rewrote the code in a way that avoids that

Clicking through plots in Shiny app

In my Shiny app, I use a for loop to make different plots and I would like the user to be able to click through each one. How would I achieve this as it currently just goes to the final plot?
library(shiny)
server <- function(input, output, session) {
# data
v <- c(9,8,7,8,9,5,6,7,4,3)
w <- c(3,4,2,3,3,3,2,3,4,5)
x <- c(1,3,4,6,2,4,6,8,6,3)
y <- c(4,5,2,4,2,1,2,5,7,8)
z <- c(5,9,8,6,4,6,8,9,6,7)
df <- data.frame(v, w, x, y, z)
# initial plot that will allow user to change parameters (haven't implemented yet)
output$plot <- renderPlot(plot(df[[1]],df[[2]]))
# wait until the button is triggered
observeEvent(input$run, {
for (i in 5){
output$plot <- renderPlot(plot(df[[1]],df[[i]], main = i))
}
})
}
ui <- fluidPage(
actionButton("run", "Generate"),
plotOutput("plot")
)
shinyApp(ui = ui, server = server)
You just need to use the variable that will maintain the count for each click:
library(shiny)
server <- function(input, output, session) {
# data
v <- c(9,8,7,8,9,5,6,7,4,3)
w <- c(3,4,2,3,3,3,2,3,4,5)
x <- c(1,3,4,6,2,4,6,8,6,3)
y <- c(4,5,2,4,2,1,2,5,7,8)
z <- c(5,9,8,6,4,6,8,9,6,7)
df <- data.frame(v, w, x, y, z)
# initial plot that will allow user to change parameters (haven't implemented yet)
output$plot <- renderPlot(plot(df[[1]],df[[2]]))
count<-0 # This is the counter which keeps track on button count
observeEvent(input$run, {
count <<- count + 1 # Increment the counter by 1 when button is click
if(count<6){
# Draw the plot if count is less than 6
output$plot <- renderPlot(plot(df[[1]],df[[count]],main = count))
}
else{
# Reset the counter if it is more than 5
count <- 0
}
})
}
ui <- fluidPage(
actionButton("run", "Generate"),
plotOutput("plot")
)
shinyApp(ui = ui, server = server)
Instead of using for loop you can try by directly using the action button click count i.e. input$run.The following code will generate the plots one by one till the click count is less than or equal to 5 and then returns to initial plot as soon the as click count exceeds 5. You can modify the else statement as per your wish.
observeEvent(input$run, {
if(input$run <= 5){
output$plot <- renderPlot(plot(df[[1]],df[[input$run]], main = input$run))
}else output$plot <- renderPlot(plot(df[[1]],df[[2]]))
})
Hope this might be helpful

Filtering reactive data in an R Shiny App

I have a dataframe that has these columns:
document, user, month, views
I am using a selectInput to filter the data by document.
I want to plot a (Plotly) line chart of views per month, for each user, for the selected document.
E.g. If one filters to a document for which ten users exist, I want to display ten plots, each showing the relevant user's views per month.
At current:
- I filter the data to the selected document (dplyr).
- I pass the filtered data to a function.
- In the function, I loop through the current document's users.
- In each loop, I filter the data to the current user (dplyr), and append a Plotly output to a output list.
- At the end of the function, I return the output list.
- The result of the function is assigne to a UI output.
The app successfully runs, but where the plots should display, I get a Result must have length x, not y error.
How would you go about this? I appreciate any advice you can give me.
For security reasons I cannot share my existing code, sorry - I understand that it's not very useful.
Edit: I've created a minimal reproducible example, based on this.
The process has changed slightly from my original question, mainly that I'm not using a separate function.
library(plotly)
library(tidyverse)
# DATA
data <- data.frame(
document= c("doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc1","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2","doc2"),
user= c("user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user3","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user1","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user2","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4","user4"),
month= as.Date(c("2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01")),
views= c(19,39,34,3,25,5,1,16,37,21,46,34,23,0,8,10,46,3,47,16,32,4,44,42,12,8,27,39,28,30,26,45,49,38,32,32,1,16,23,34,41,46,37,0,23,44,10,3,43,43,22,38,1,33,11,15,8,21,37,17,7,29,1,33,47,45,37,20,9,41,37,18,30,46,24,45,48,42,49,3,10,17,46,6,12,29,13,6,4,44,37,26,43,5,19,28,44,20,35,40,32,20,41,46,25,47,35,3,25,25,41,5,26,32)
)
# SERVER
server <- shinyServer(function(input, output) {
output$plots <- renderUI({
doc_data <- filter(data, document == input$select_doc) # This is the breaking line
plot_output_list <- lapply(1:length(unique(doc_data$user)), function(i) {
plotname <- paste("plot", i, sep="")
plotlyOutput(plotname)
})
do.call(tagList, plot_output_list)
})
for (i in 1:length(unique(doc_data$user))) {
local({
local_i <- i
doc_users <- unique(doc_data$user)
plotname <- paste("plot", local_i, sep="")
plot_data <- filter(doc_data, user == doc_users[local_i]) %>%
arrange(month)
output[[plotname]] <- renderPlotly({
p <- plot_ly(x= plot_data$month, y= plot_data$views, type = 'scatter', mode = 'lines')
p$elementId <- NULL
p
})
})
}
})
# UI
ui <- shinyUI(pageWithSidebar(
headerPanel("Minimum reproducible example"),
sidebarPanel(
selectInput("select_doc", choices= unique(data$document), label="", selected= 'doc1')#,
),
mainPanel(
uiOutput("plots")
)
))
# RUN
shinyApp(ui, server)

How to render multiple output from the same analysis without executing it multiple time? (Shiny)

I am writing an shiny app in which contains an stochastic function generates four objects - one plot and three tables. However, I want to render each object in different tabs without being executing the function four times since this stochastic function will generates four different versions. I have been researched online and find a lot people recommend "reactive()" but I still don't quite understand how to apply it to my problem. How can I use those four objects on rendering with only one execution on the function?
My "server.R" structure basically looks like the below:
shinyServer(function(input, output) {
stochastic_function() {
...
plot1 <- ...
table1 <- ...
table2 <- ...
table3 <- ...
result <- list(plot, table1, table2, table3)
return(result)
}
output$plot <- renderPlot({
})
output$table1 <- renderTable({
})
output$table2 <- renderTable({
})
output$table3 <- renderTable({
})
...
So, I have tried something like below for the stochastic function:
model <- eventReactive(input$goButton, {
reactive(WG_Model(cdata = cdata(), # load data from outside env
sdata = sdata(), # load data from outside env
N = input$n,
end_date = input$end_date,
cpx_goal = input$cpx,
N_new = input$n2,
end_date_new = input$end_date2,
spend_range = input$s_range,
spend_incr = input$s_incr
)
)
})
The idea is to add an "GoButton" to initiate the function and then save all outputs in a reactive fun(). So I can render each output with:
output$plot <- renderPlot({
model$gplot
})
output$table <- renderTable({
model$table
})
# Render UI section
output$tb <- renderUI({
tabsetPanel(tabPanel("About Model", plotOutput("plot")),
tabPanel("About Model", tableOutput("table")))
})
However, I only got "Error: object of type 'closure' is not subsettable" in the UI output. Which part did I miss?
If your model() is a list and contains data for all tables and a plot, it should work as in my example.
In this app, after pressing a button, a random number and data for a table and a plot are generated. Then the number, data for table and a plot are returned as a list and rendered with appropriate render* functions.
This app illustrates that the model function won't be re-run after accessing it with model() in other reactive functions.
However, there is an odd thing...the plot is not always rendered. You sometimes have to click the button few times to get the plot. The table is working always.
library(shiny)
ui <- shinyUI(fluidPage(
br(),
actionButton("numb", "generate a random numbers"),
br(),
br(),
verbatimTextOutput("text"),
plotOutput("plot"),
tableOutput("table")
))
server <- shinyServer(function(input, output) {
model <- eventReactive(input$numb, {
# draw a random number and print it
random <- sample(1:100, 1)
print(paste0("The number is: ", random))
# generate data for a table and plot
data <- rnorm(10, mean = 100)
table <- matrix(data, ncol = 2)
# create a plot
Plot <- plot(1:length(data), data, pch = 16, xlab ="", ylab = "")
# return all object as a list
list(random = random, Plot = Plot, table = table)
})
output$text <- renderText({
# print the random number after accessing "model" with brackets.
# It doesn't re-run the function.
youget <- paste0("After using model()$random you get: ", model()$random,
". Compare it with a value in the console")
print(youget)
youget
})
output$plot <- renderPlot({
# render saved plot
model()$Plot
})
output$table <- renderTable({
model()$table
})
})
shinyApp(ui = ui, server = server)

Resources