Unable to generate the candle charts on dialog box in R shiny - r

I have a R shiny dashboard for stocks analysis. This dashboard has the date at top as driving criteria. The symbols are selected based on that.
The detailed information of these stocks are shown further one by one.
For demo purpose the data is displayed in the attached code.
One button is also added to the dashboard for each of the symbol.
On clicking the button the candle stick graph of that symbol is expected.
In present code when the button is clicked the graph is shown in the Plots pane of the RStudio and not in the graph..but error message subscript out of bounds is shown.
This is shown in the image .
Kindly suggest the changes to display the graph in the popup window.
Image in Plot Pange
library(quantmod)
library(shiny)
getSymbols("AAPL", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("MSFT", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("META", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("ORCL", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("TSLA", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("GOOG", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
df_AAPL <- as.data.frame(AAPL)
df_AAPL$DATE <- index(AAPL)
rownames(df_AAPL) <- NULL
names(df_AAPL) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_AAPL$SYMBOL <- 'AAPL'
df_MSFT <- as.data.frame(MSFT)
df_MSFT$DATE <- index(MSFT)
rownames(df_MSFT) <- NULL
names(df_MSFT) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_MSFT$SYMBOL <- 'MSFT'
df_META <- as.data.frame(META)
df_META$DATE <- index(META)
rownames(df_META) <- NULL
names(df_META) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_META$SYMBOL <- 'META'
df_ORCL <- as.data.frame(ORCL)
df_ORCL$DATE <- index(ORCL)
rownames(df_ORCL) <- NULL
names(df_ORCL) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_ORCL$SYMBOL <- 'ORCL'
df_TSLA <- as.data.frame(TSLA )
df_TSLA$DATE <- index(TSLA)
rownames(df_TSLA) <- NULL
names(df_TSLA) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_TSLA$SYMBOL <- 'TSLA'
df_GOOG <- as.data.frame(GOOG)
df_GOOG$DATE <- index(GOOG)
rownames(df_GOOG) <- NULL
names(df_GOOG) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_GOOG$SYMBOL <- 'GOOG'
df_all <- rbind(df_AAPL, df_MSFT,df_META,df_ORCL,df_TSLA,df_GOOG)
df_all[, c('SYMBOL','DATE','OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED')]
df_rep_date <- data.frame('RunDate'= character(),'ListStocks' = character(), stringsAsFactors=FALSE)
df_rep_date[1,] <- c("2020-01-06", 'AAPL,GOOG,TSLA')
df_rep_date[2,] <- c("2021-01-04", 'ORCL')
df_rep_date[3,] <- c("2022-01-04", 'META,MSFT')
#df_rep_date[4,] <- c("2022-01-07", 'MSFT')
df_rep_date$RunDate <- as.Date(df_rep_date$RunDate)
v_lst_sel_dates <-c(df_rep_date$RunDate)
func_common_crt_lst <- function(...){ x <- list(...); return(x)}
func_1symb_plot <- function(p_symb){
df_tmp_hist_dat = df_all[df_all$SYMBOL == p_symb,c("DATE" ,"OPEN","HIGH","LOW" ,"CLOSE","VOLUME" )]
v_df_dly_dat_6mnth_xts <- xts(df_tmp_hist_dat[, -1], order.by = df_tmp_hist_dat[, 1])
v_grph_op <- candleChart( v_df_dly_dat_6mnth_xts,name = p_symb, type = "auto", up.col = "green", dn.col = "red",
theme = "white",plot = TRUE,TA = "addVo();addSMA(n = 1, on = 1, overlay = TRUE, col ='black');
addSMA(n = 7, on = 1, overlay = TRUE, col ='gold'); addSMA(n = 14, on = 1, overlay = TRUE, col ='brown');addMACD(); addBBands();addRSI();addOBV();")
return(v_grph_op)}
func_1symb_tab <- function(p_symb){
df_tmp_hist_dat = df_all[df_all$SYMBOL == p_symb,c("DATE" ,"OPEN","HIGH","LOW" ,"CLOSE","VOLUME" )]
df_tmp_hist_dat <- df_tmp_hist_dat[1:5,]
df_tmp_hist_dat$DATE <- as.Date(df_tmp_hist_dat$DATE)
v_tab_op <- df_tmp_hist_dat
}
simpUI <- function(id) {
tagList(selectInput(NS(id, 'RunDate'), "Run Date", v_lst_sel_dates),
textOutput(NS(id,'date_output')),
textOutput(NS(id,'lst_symb_output')),
uiOutput(NS(id,"myplot"))
)
}
simpServer <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
string <- reactive(input$RunDate)
output$date_output <- renderText(string())
v_lst_symbol <- reactive(df_rep_date[df_rep_date$RunDate == input$RunDate,]$ListStocks)
output$lst_symb_output <- renderText(v_lst_symbol())
observeEvent(input$RunDate, {
print(v_lst_symbol())
symbs <- read.table(text = v_lst_symbol(), sep = ",", colClasses = "character")
print(symbs)
lapply(symbs[1,], function(v_symb){
v_symb_name = paste0(v_symb, '_name')
output[[paste0(v_symb, '_name')]] = renderText(v_symb_name)
output[[paste0(v_symb, '_table')]] <- renderTable(func_1symb_tab(v_symb))
observeEvent({input[[paste0(v_symb, '_cndl_chart')]]},{
plt_cndl <- func_1symb_plot(v_symb)
print(' before showModal')
showModal(modalDialog(title = v_symb, size = "l",renderPlot(plt_cndl)))
print("after showmodel ")
})
})
})
output$myplot <- renderUI({
symbs <- read.table(text = v_lst_symbol(), sep = ",", colClasses = "character")
tagList(
lapply(symbs[1,], function(v_symb){
id1 <- paste0(v_symb, '_name')
id3 <- paste0(v_symb, '_table')
id4 <- paste0(v_symb, '_cndl_chart')
fluidRow(
func_common_crt_lst(htmlOutput(ns(id1)),
tableOutput(ns(id3)),
actionButton(ns(id4), ns(id4))))
})
)
})
})
}
ui <- fluidPage(fluidRow(simpUI("par1")))
server <- function(input, output, session) {
simpServer("par1")
}
shinyApp(ui = ui, server = server)

Your code is by far not minimal and it needed quite some amount of time to strip all the unnecessary parts away to find out what you are trying. For future reference you may get more help if you minimize your code.
Your code has several issues:
You cannot use renderPlot without a corresponding plotOutput. That is the main issue why your plot does not show up. Hence, you need to place a plotOutput in your modal and add an additional renderPlot to fill it.
Your module is somewhat useless and you shoudl rather create a module around the elements symbol name, table and modal action button.
Using some loops helps tremendously to avoid this massive code duplictation.
Having said that, here's a working example which refactored your code quite extensively and made use of the tidyverse to simplify some of the data operations you are doing.
library(quantmod)
library(shiny)
library(dplyr)
library(purrr)
library(stringr)
get_data <- function(symbols = c("AAPL", "MSFT", "META", "ORCL",
"TSLA", "GOOG")) {
syms <- getSymbols(symbols, from = "2020/01/01",
to = Sys.Date(), periodicity = "daily")
map_dfr(syms, function(sym) {
raw_data <- get(sym)
raw_data %>%
as_tibble() %>%
set_names(c("OPEN", "HIGH", "LOW", "CLOSE", "VOLUME", "ADJUSTED")) %>%
mutate(SYMBOL = sym,
DATE = index(raw_data)) %>%
select(SYMBOL, DATE, OPEN, HIGH, LOW, CLOSE, VOLUME, ADJUSTED)
})
}
if (!exists("df_all")) {
df_all <- get_data()
}
df_rep_data <- tribble(~ RunDate, ~ ListStocks,
"2020-01-06", "AAPL, GOOG, TSLA",
"2021-01-04", "ORCL",
"2022-01-04", "META, MSFT") %>%
mutate(RunDate = as.Date(RunDate))
make_candle_chart <- function(symbol, dat = df_all) {
vals <- dat %>%
filter(SYMBOL == symbol)
ts <- xts(vals %>%
select(OPEN, HIGH, LOW, CLOSE, VOLUME),
order.by = vals %>% pull(DATE))
candleChart(ts, name = symbol, type = "auto",
up.col = "green", dn.col = "red", theme = "white", plot = TRUE,
TA = c(addVo(),
addSMA(n = 1, on = 1, overlay = TRUE, col = "black"),
addSMA(n = 7, on = 1, overlay = TRUE, col = "gold"),
addSMA(n = 14, on = 1, overlay = TRUE, col = "brown"),
addMACD(),
addBBands(),
addRSI(),
addOBV()))
}
make_table <- function(symbol, dat = df_all) {
dat %>%
filter(SYMBOL == symbol) %>%
select(DATE, OPEN, HIGH, LOW, CLOSE, VOLUME) %>%
slice(1:5)
}
symb_ui <- function(id) {
ns <- NS(id)
tagList(
tags$h4(textOutput(ns("symbol"))),
tableOutput(ns("table")),
actionButton(ns("show_modal"), "Show Candle Chart")
)
}
symb_server <- function(id, get_symbol_name) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
output$symbol <- renderText(get_symbol_name())
output$table <- renderTable(make_table(get_symbol_name()))
output$cndl_chart <- renderPlot(make_candle_chart(get_symbol_name()))
observeEvent(input$show_modal, {
mdl <- modalDialog(title = get_symbol_name(),
size = "l",
plotOutput(ns("cndl_chart")))
showModal(mdl)
})
})
}
ui <- fluidPage(
selectInput("run_date", "Run Date", df_rep_data %>% pull(RunDate)),
tags$h2(textOutput("date_output")),
tags$h3(textOutput("lst_symb_output")),
uiOutput("symbols_output")
)
server <- function(input, output, session) {
handler <- list()
get_syms <- list()
output$date_output <- renderText(req(input$run_date))
output$lst_symb_output <- renderText({
df_rep_data %>%
filter(RunDate == req(input$run_date)) %>%
pull(ListStocks)
})
output$symbols_output <- renderUI({
symbols <- df_rep_data %>%
filter(RunDate == req(input$run_date)) %>%
pull(ListStocks) %>%
str_split(fixed(", ")) %>%
unlist()
syms <- vector("list", length(symbols)) %>%
set_names(symbols)
for (sym in symbols) {
## this local construct is needed for scoping cf.
## https://gist.github.com/bborgesr/e1ce7305f914f9ca762c69509dda632e
local({
my_sym <- sym
syms[[my_sym]] <<- symb_ui(my_sym)
get_syms[[my_sym]] <<- reactive(my_sym)
handler[[my_sym]] <<- symb_server(my_sym, get_syms[[my_sym]])
})
}
tagList(syms)
})
}
shinyApp(ui = ui, server = server)

Related

Add text box for each looping shiny page elements

I need to add a textbox and button for each of the iteration. User will enter the value in the textbox and button will write the value in textbpx to a file along with other information. This other informatin can be taken from current graph item . This needs to be done in for each iteration similar to the graphs as shown for each symbol as below
library('quantmod')
getSymbols("AAPL", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("MSFT", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("FB", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("ORCL", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
df_AAPL <- as.data.frame(AAPL)
df_AAPL$DATE <- index(AAPL)
rownames(df_AAPL) <- NULL
names(df_AAPL) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_AAPL$SYMBOL <- 'AAPL'
df_MSFT <- as.data.frame(MSFT)
df_MSFT$DATE <- index(MSFT)
rownames(df_MSFT) <- NULL
names(df_MSFT) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_MSFT$SYMBOL <- 'MSFT'
df_FB <- as.data.frame(FB)
df_FB$DATE <- index(FB)
rownames(df_FB) <- NULL
names(df_FB) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_FB$SYMBOL <- 'FB'
df_ORCL <- as.data.frame(ORCL)
df_ORCL$DATE <- index(ORCL)
rownames(df_ORCL) <- NULL
names(df_ORCL) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_ORCL$SYMBOL <- 'ORCL'
df_all <- rbind(df_AAPL, df_MSFT,df_FB,df_ORCL)
df_all[, c('SYMBOL','DATE','OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED')]
library(shiny)
#unique(df_all$DATE)
df_rep_date <- data.frame('RunDate'= character(),'ListStocks' = character(), stringsAsFactors=FALSE)
df_rep_date[1,] <- c("2020-01-06", 'AAPL,MSFT')
df_rep_date[2,] <- c("2021-01-04",'ORCL,AAPL')
df_rep_date[3,] <- c("2022-01-04", 'FB,ORCL')
df_rep_date$RunDate <- as.Date(df_rep_date$RunDate)
v_lst_sel_dates <-c(df_rep_date$RunDate)
func_1symb_plot <- function(p_symb){
#p_symb = 'AAPL'
df_tmp_hist_dat = df_all[df_all$SYMBOL == p_symb,c("DATE" ,"OPEN","HIGH","LOW" ,"CLOSE","VOLUME" )]
v_df_dly_dat_6mnth_xts <- xts(df_tmp_hist_dat[, -1], order.by = df_tmp_hist_dat[, 1])
v_grph_op <- candleChart( v_df_dly_dat_6mnth_xts,name = p_symb, type = "auto", up.col = "green", dn.col = "red",
theme = "white",plot = TRUE,TA = "addVo();addSMA(n = 1, on = 1, overlay = TRUE, col ='black');
addSMA(n = 7, on = 1, overlay = TRUE, col ='gold'); addSMA(n = 14, on = 1, overlay = TRUE, col ='brown');addMACD(); addBBands();addRSI();addOBV();")
return(v_grph_op)}
simpUI <- function(id) {
tagList(selectInput(NS(id, 'RunDate'), "Run Date", v_lst_sel_dates),
textOutput(NS(id,'date_output')),
textOutput(NS(id,'lst_symb_output')),
uiOutput(NS(id,"myplot"))
)
}
simpServer <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
string <- reactive(input$RunDate)
output$date_output <- renderText(string())
v_lst_symbol <- reactive(df_rep_date[df_rep_date$RunDate == input$RunDate,]$ListStocks)
output$lst_symb_output <- renderText(v_lst_symbol())
observeEvent(input$RunDate, {
print(v_lst_symbol())
symbs <- read.table(text = v_lst_symbol(), sep = ",", colClasses = "character")
print(symbs)
lapply(symbs[1,], function(v_symb){
v_symb_name = paste0(v_symb, '_name')
output[[paste0(v_symb, '_name')]] = renderText(v_symb_name)
output[[paste0(v_symb, '_plot')]] <- renderPlot(func_1symb_plot(v_symb))
})
})
output$myplot <- renderUI({
symbs <- read.table(text = v_lst_symbol(), sep = ",", colClasses = "character")
tagList(
lapply(symbs[1,], function(v_symb){
id1 <- paste0(v_symb, '_name')
id2 <- paste0(v_symb, '_plot')
textOutput(ns(id1))
plotOutput(ns(id2))
# add the textbox and the button.
# this will be for each of the element in the loop
})
)
})
})
}
ui <- fluidPage(fluidRow(simpUI("par1")))
server <- function(input, output, session) {
simpServer("par1")
}
shinyApp(ui = ui, server = server)

rshiny dashboard by looping individual values

There is one dashboard where need to put the analysis for each of the element selected list.
I have created a setup as below fot testing
Need to generate the graphs for the date for the individual symbols as shown below.
The date is selected from the drop down. The list of symbols is provided by df_rep_date for this date.
This list is iterated and the graph is genereated for the symbols in the list as shown below.
install.packages('quantmod')
library('quantmod')
getSymbols("AAPL", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("MSFT", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("FB", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
getSymbols("ORCL", from = "2020/01/01",to = Sys.Date(), periodicity = "daily")
df_AAPL <- as.data.frame(AAPL)
df_AAPL$DATE <- index(AAPL)
rownames(df_AAPL) <- NULL
names(df_AAPL) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_AAPL$SYMBOL <- 'AAPL'
df_MSFT <- as.data.frame(MSFT)
df_MSFT$DATE <- index(MSFT)
rownames(df_MSFT) <- NULL
names(df_MSFT) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_MSFT$SYMBOL <- 'MSFT'
df_FB <- as.data.frame(FB)
df_FB$DATE <- index(FB)
rownames(df_FB) <- NULL
names(df_FB) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_FB$SYMBOL <- 'FB'
df_ORCL <- as.data.frame(ORCL)
df_ORCL$DATE <- index(ORCL)
rownames(df_ORCL) <- NULL
names(df_ORCL) <- c('OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED','DATE')
df_ORCL$SYMBOL <- 'ORCL'
df_all <- rbind(df_AAPL, df_MSFT,df_FB,df_ORCL)
df_all[, c('SYMBOL','DATE','OPEN','HIGH','LOW','CLOSE','VOLUME','ADJUSTED')]
library(shiny)
#unique(df_all$DATE)
df_rep_date <- data.frame('RunDate'= character(),'ListStocks' = character(), stringsAsFactors=FALSE)
df_rep_date[1,] <- c("2020-01-06", 'AAPL,MSFT')
df_rep_date[2,] <- c("2021-01-04",'ORCL,AAPL')
df_rep_date[3,] <- c("2022-01-04", 'FB,ORCL')
df_rep_date$RunDate <- as.Date(df_rep_date$RunDate)
v_lst_sel_dates <-c(df_rep_date$RunDate)
func_1symb_plot <- function(p_symb){
p_symb = 'AAPL'
df_tmp_hist_dat = df_all[df_all$SYMBOL == p_symb,c("DATE" ,"OPEN","HIGH","LOW" ,"CLOSE","VOLUME" )]
v_df_dly_dat_6mnth_xts <- xts(df_tmp_hist_dat[, -1], order.by = df_tmp_hist_dat[, 1])
v_grph_op <- candleChart( v_df_dly_dat_6mnth_xts,name = v_symb, type = "auto", up.col = "green", dn.col = "red",
theme = "white",plot = TRUE,TA = "addVo();addSMA(n = 1, on = 1, overlay = TRUE, col ='black');
addSMA(n = 7, on = 1, overlay = TRUE, col ='gold'); addSMA(n = 14, on = 1, overlay = TRUE, col ='brown');addMACD(); addBBands();addRSI();addOBV();")
return(v_grph_op)}
simpUI <- function(id) {
tagList(selectInput(NS(id, 'RunDate'), "Run Date", v_lst_sel_dates),
textOutput(NS(id,'date_output')),
textOutput(NS(id,'lst_symb_output')),
textOutput(NS(id,'test_text'))),
fluidPage( for (v_symb in lst_symb_output){
renderTex('v_symb_name')
plotOutput(v_symb)
})
simpServer <- function(id) {
moduleServer(id, function(input, output, session) {
string <- reactive(input$RunDate)
output$date_output <- renderText(string())
v_lst_symbol <- reactive(df_rep_date[df_rep_date$RunDate == input$RunDate,]$ListStocks)
output$lst_symb_output <- renderText(v_lst_symbol())
for (v_symb in v_lst_symbol()){
v_symb_name = paste0(v_symb, '_name')
output$v_symb_name = v_symb
output$v_symb <- renderPlot(func_1symb_plot(v_symb))
}
})
}
ui <- fluidPage(fluidRow(simpUI("par1")))
server <- function(input, output, session) {
simpServer("par1")
}
shinyApp(ui = ui, server = server)
Try this
df_rep_date <- data.frame('RunDate'= character(),'ListStocks' = character(), stringsAsFactors=FALSE)
df_rep_date[1,] <- c("2020-01-06", 'AAPL')
df_rep_date[2,] <- c("2021-01-04", 'ORCL')
df_rep_date[3,] <- c("2022-01-04", 'FB,MSFT')
#df_rep_date[4,] <- c("2022-01-07", 'MSFT')
df_rep_date$RunDate <- as.Date(df_rep_date$RunDate)
v_lst_sel_dates <-c(df_rep_date$RunDate)
func_1symb_plot <- function(p_symb){
#p_symb = 'AAPL'
df_tmp_hist_dat = df_all[df_all$SYMBOL == p_symb,c("DATE" ,"OPEN","HIGH","LOW" ,"CLOSE","VOLUME" )]
v_df_dly_dat_6mnth_xts <- xts(df_tmp_hist_dat[, -1], order.by = df_tmp_hist_dat[, 1])
v_grph_op <- candleChart( v_df_dly_dat_6mnth_xts,name = p_symb, type = "auto", up.col = "green", dn.col = "red",
theme = "white",plot = TRUE,TA = "addVo();addSMA(n = 1, on = 1, overlay = TRUE, col ='black');
addSMA(n = 7, on = 1, overlay = TRUE, col ='gold'); addSMA(n = 14, on = 1, overlay = TRUE, col ='brown');addMACD(); addBBands();addRSI();addOBV();")
return(v_grph_op)}
simpUI <- function(id) {
tagList(selectInput(NS(id, 'RunDate'), "Run Date", v_lst_sel_dates),
textOutput(NS(id,'date_output')),
textOutput(NS(id,'lst_symb_output')),
uiOutput(NS(id,"myplot"))
)
}
simpServer <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
string <- reactive(input$RunDate)
output$date_output <- renderText(string())
v_lst_symbol <- reactive(df_rep_date[df_rep_date$RunDate == input$RunDate,]$ListStocks)
output$lst_symb_output <- renderText(v_lst_symbol())
observeEvent(input$RunDate, {
print(v_lst_symbol())
symbs <- read.table(text = v_lst_symbol(), sep = ",", colClasses = "character")
print(symbs)
lapply(symbs[1,], function(v_symb){
v_symb_name = paste0(v_symb, '_name')
output[[paste0(v_symb, '_name')]] = renderText(v_symb_name)
output[[paste0(v_symb, '_plot')]] <- renderPlot(func_1symb_plot(v_symb))
})
})
output$myplot <- renderUI({
symbs <- read.table(text = v_lst_symbol(), sep = ",", colClasses = "character")
tagList(
lapply(symbs[1,], function(v_symb){
id1 <- paste0(v_symb, '_name')
id2 <- paste0(v_symb, '_plot')
textOutput(ns(id1))
plotOutput(ns(id2))
})
)
})
})
}
ui <- fluidPage(fluidRow(simpUI("par1")))
server <- function(input, output, session) {
simpServer("par1")
}
shinyApp(ui = ui, server = server)

R Shiny, how to use highcharts drilldown in shinyapp depending on selectinput widget result?

I am trying to create a drill down chart using highcharts package, the chart must be dependent on the selectinput results.
The current error is
Error in .getReactiveEnvironment()$currentContext() :
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)
the expected or desired output is to get dynamic plot depending on the selected value.
library (shinyjs)
library (tidyr)
library (data.table)
library (highcharter)
library (dplyr)
library (shinydashboard)
library (shiny)
x <- c("Farm","Farm","Farm","City","City","City","Ocean","Ocean")
y <- c("Sheep","Sheep","Cow","Car","Bus","Bus","Boat","Boat")
z <- c("Bill","Tracy","Sandy","Bob","Carl","Newt","Fig","Tony")
a <- c(1,1,1,1,1,1,1,1)
b <- c(3,2,5,1,3,5,1,5)
c <- c(4,6,7,7,4,2,1,6)
xxxx <- data.frame(x, y, z, a, b, c, stringsAsFactors = FALSE)
header <- dashboardHeader()
body <- dashboardBody(
selectInput("selectid","Select a Measurement",choices=c("a","b","c"),selected = "a"),
highchartOutput("Working"))
sidebar <- dashboardSidebar()
ui <- dashboardPage(header, sidebar, body)
server <- function(input, output, session) {
zzz<-reactive({
#browser
select(xxxx,one_of(c("x", "y", "z", input$selectid)))})
output$Working <- renderHighchart({
summarized <- zzz() %>%
group_by(x) %>%
summarize(Quantity = sum(!!sym(input$selectid)))
summarized <- arrange(summarized, desc(Quantity))
tibbled <- tibble(name = summarized$x, y = summarized$Quantity)
# This time, click handler is needed.
drilldownHandler <-
JS(
"function(event) {Shiny.onInputChange('ClickedInput', event.point.drilldown);}")
installDrilldownReceiver <- JS("function() {
var chart = this;
Shiny.addCustomMessageHandler('drilldown', function(message) {
var point = chart.get(message.point)
chart.addSeriesAsDrilldown(point, message.series);
});
}")
highchart() %>%
hc_chart(events = list(load = installDrilldownReceiver, drilldown = drilldownHandler)) %>%
hc_xAxis(type = "category") %>%
hc_add_series(tibbled, "column", hcaes(x = name, y = y, drilldown = name, id = name), color = "#E4551F") %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_drilldown(allowPointDrilldown = TRUE)
})
observeEvent(
#browser
input$ClickedInput, {
levels <- strsplit(input$ClickedInput, "_", fixed = TRUE)[[1]]
resemblences <- c("x", "y", "z")
dataSubSet <- reactive({
#browser()
zzz()
})
for (i in 1:length(levels)) {
dataSubSet() <- zzz()[zzz()[[resemblences[i]]] == levels[i],]
}
normalized <- data.frame(category = dataSubSet()[[resemblences[length(levels) + 1]]], amount = input$selectid)
summarized <- normalized %>%
group_by(category) %>%
summarize(Quantity = sum(amount))
summarized <- arrange(summarized, desc(Quantity))
tibbled <- tibble(name = summarized$category, y = summarized$Quantity)
nextLevelCodes = lapply(tibbled$name, function(fac) {
paste(c(levels, as.character(fac)), collapse = "_")
}) %>% unlist
tibbled$id = nextLevelCodes
if (length(levels) < length(resemblences) - 1) {
tibbled$drilldown = nextLevelCodes
}
session$sendCustomMessage("drilldown", list(
series = list(
type = "column",
name = paste(levels, sep = "_"),
data = list_parse(tibbled)
),
point = input$ClickedInput
))
})
output$trial <- renderText({input$ClickedInput})
}
shinyApp(ui, server)

Performance problems in R's Shiny on huge (?) dataset

I have a dataset of ~10.000 address pairs (origin, destination) which consists of two sources - a database and a CSV-file. I am visualizing those pairs of addresses by two different marker types and I visualize the connections between those pairs with a line. It's possible to toggle the visibility of origins, destinations, and connections. It's also possible to draw a polygon on the map to frame markers and then visualize the corresponding markers and connections (you can choose if the polygon should frame origins, destinations or both). And it's possible to toggle the datasource (CSV or database) and choose data by date.
All of this works quite well, I just wanted to make clear where and that I need to use reactive values. But the performance is way to slow. It takes a lot of time to load this application when running it with RStudio and it could not be loaded on Shiny Server because the connection breaks down. I'm don't use the Pro version of Shiny Server where the timeout is not settable out of the box.
I tried to speed up the application by using the leafletProxy as often as possible.
df.data.db <- getDataFromDb() #external function
df.data.csv <- getDataFromCsv() #external function
df.data.total <- rbind(df.data.db,df.data.csv)
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
tags$head(tags$style(HTML('.dest {color: rgba(11, 221, 25, 0.7);}'))),
tags$head(tags$style(HTML('.orig {color: rgba(255,100,20);}'))),
leafletOutput("map", height = "85%"),
fluidRow(
column(
3,
p(tags$b("Datasets")),
materialSwitch(inputId = "useDatabase", label = "database",value=TRUE),
materialSwitch(inputId = "useExcel", label = "excel",value=TRUE)),
column(
3,
p(),
dateRangeInput('dateRange',
label = 'Date range input: yyyy-mm-dd',
start = "2016-12-26",
end = Sys.Date(),
min = "2016-12-26",
max = Sys.Date()),
p(),
textOutput("number_of_data")
),
column(3,
p(),
actionButton("remove", "Remove shapes")),
column(3,
p(tags$b("Connections")),
textOutput("number_of_connections"))
)
)
server <- function(input, output, session) {
reactiveData <- reactiveValues(
markers = data.frame(lat = numeric(), lon = numeric()),
allPoly = data.frame(lat = numeric(), lon = numeric()),#should polygon frame all markers
origPoly = data.frame(lat = numeric(), lon = numeric()),#only origin markers
destPoly = data.frame(lat = numeric(), lon = numeric()),#only destination markers
shapeState = "poly_all",#what polygon type is drawn
connections=0
)
#used subset of data depending of the chosen date
mydata <- reactive({
base = base_data()
from <- input$dateRange[1]
to <- input$dateRange[2]
return(base[base$date>=from & base$date<=to,])
})
#choose data source (csv or db)
base_data <- reactive({
mydf = data.frame(orig_lat=numeric(),
orig_lon=numeric(),
dest_lat=numeric(),
dest_lon=numeric(),
date=as.Date(character()))
if(input$useExcel==TRUE && input$useDatabase==TRUE)
mydf = df.data.total
else if(input$useExcel==FALSE && input$useDatabase==TRUE)
mydf = df.data.db
else if(input$useExcel==TRUE && input$useDatabase==FALSE)
mydf = df.data.csv
reactiveData$connections <- nrow(mydf)
return(mydf)
})
#show / hide connections
observe({
leafletProxy("map",session = session) %>%
clearShapes() %>%
clearGroup("Connections")
conn.data <- mydata();
for(i in 1:nrow(conn.data)) {
row <- conn.data[i,]
leafletProxy("map",session = session) %>% addPolygons(lat=c(row$orig_lat,row$dest_lat),lng=c(row$orig_lon,row$dest_lon),group="Connections",weight=0.5)
}
})
#remove all customized stuff
observeEvent(input$remove,{
reactiveData$markers <- data.frame(lat = numeric(), lon = numeric())
reactiveData$allPoly <- data.frame(lat = numeric(), lon = numeric())
reactiveData$origPoly <- data.frame(lat = numeric(), lon = numeric())
reactiveData$destPoly <- data.frame(lat = numeric(), lon = numeric())
reactiveData$shapeState <- "poly_all"
reactiveData$connections<-0
leafletProxy("map",session = session) %>%
clearShapes() %>%
clearGroup("polygon") %>%
clearGroup("polymarkers")%>%
clearGroup("polyconnections") %>%
showGroup("Origins") %>%
showGroup("Destinations") %>%
clearGroup("tempmarkers")
})
#my map
output$map <- renderLeaflet({
leaflet(data=mydata()) %>%
addTiles()%>%
setView("7.126501","48.609749", 10) %>%
addMarkers(
lng=~dest_lon,
lat=~dest_lat,
icon = uix.destMarker,
group = "Destinations",
layerId = "dest_layer",
clusterId = "dest_cluster",
clusterOptions = markerClusterOptions(
removeOutsideVisibleBounds = TRUE,
iconCreateFunction=js.destclusters
)) %>%
addMarkers(
lng=~orig_lon,
lat=~orig_lat,
icon = uix.origMarker,
group = "Origins",
layerId = "orig_layer",
clusterId = "orig_cluster",
clusterOptions = markerClusterOptions(
removeOutsideVisibleBounds = TRUE,
iconCreateFunction=js.origclusters
)) %>%
addLayersControl(overlayGroups = c("Origins","Destinations","Connections"))
})
#print markers for polygon on map
observeEvent(input$map_click,{
leafletProxy("map",session = session) %>%
hideGroup("Connections")
if(nrow(reactiveData$allPoly)>0){
reactiveData$markers <- data.frame(lat = numeric(), lon = numeric())
reactiveData$allPoly <- data.frame(lat = numeric(), lon = numeric())
reactiveData$origPoly <- data.frame(lat = numeric(), lon = numeric())
reactiveData$destPoly <- data.frame(lat = numeric(), lon = numeric())
reactiveData$shapeState <- "poly_all"
reactiveData$connections<-0
leafletProxy("map",session = session) %>%
clearShapes() %>%
clearGroup("polygon") %>%
clearGroup("polymarkers")%>%
clearGroup("polyconnections") %>%
showGroup("Origins") %>%
showGroup("Destinations") %>%
clearGroup("tempmarkers")
}
if(nrow(reactiveData$origPoly)>0 && nrow(reactiveData$destPoly)>0){
showModal(modalDialog(
title = "Wrong workflow",
"Remove old shapes first!",
easyClose = TRUE
))
}
else{
click <- input$map_click
clat <- click$lat
clng <- click$lng
reactiveData$markers[nrow(reactiveData$markers) + 1, ] = c(clat, clng)
leafletProxy('map') %>%
addMarkers(lng = reactiveData$markers$lon,
lat = reactiveData$markers$lat,
group="polymarkers"
)
}
})
#change type of polygon by clicking on polygon. hiding connections by clicking on it
observeEvent(input$map_shape_click,{
click <- input$map_shape_click
if(click$group=="Connections"){
leafletProxy("map",session = session) %>%
hideGroup("Connections")
clat <- click$lat
clng <- click$lng
leafletProxy('map') %>%
addMarkers(lng = clng,
lat = clat)
reactiveData$markers[nrow(reactiveData$markers) + 1, ] = c(clat, clng)
}
else if(click$group =="polygon" && nrow(reactiveData$markers)==0){
tmp <- data.frame(lat = numeric(), lon = numeric())
if(reactiveData$shapeState=="poly_all") {
reactiveData$shapeState<-"poly_orig"
isolate(tmp<-reactiveData$allPoly)
reactiveData$origPoly <- rbind(reactiveData$origPoly,tmp)
reactiveData$allPoly<- data.frame(lat = numeric(), lon = numeric())
#reactiveData$destPoly <- rbind(reactiveData$destPoly,data.frame(lat = numeric(), lon = numeric()))
}
else if(reactiveData$shapeState=="poly_orig") {
reactiveData$shapeState<-"poly_dest"
isolate(tmp<-reactiveData$origPoly)
reactiveData$origPoly <- data.frame(lat = numeric(), lon = numeric())
#reactiveData$allPoly <- data.frame(lat = numeric(), lon = numeric())
reactiveData$destPoly <- rbind(reactiveData$destPoly,tmp)
}
else if(reactiveData$shapeState=="poly_dest") {
reactiveData$shapeState<-"poly_all"
isolate(tmp<-reactiveData$destPoly)
#reactiveData$origPoly <- rbind(reactiveData$origPoly,data.frame(lat = numeric(), lon = numeric()))
reactiveData$allPoly <- rbind(reactiveData$allPoly,tmp)
reactiveData$destPoly <- data.frame(lat = numeric(), lon = numeric())
}
createConnections()
leafletProxy('map') %>% # use the proxy to save computation
clearGroup("polygon") %>%
addPolygons(lat = tmp$lat, lng = tmp$lon, group="polygon",color = polyColor(),fillColor=polyColor())
}
else if(nrow(reactiveData$markers)>0){
showModal(modalDialog(
title = "Wrong workflow",
"It's too late to change the type of your selection. Please clear shapes and draw again!",
easyClose = TRUE
))
}
})
polyColor <- reactive({
if(reactiveData$shapeState=="poly_all") {
return("black")
}
else if(reactiveData$shapeState=="poly_orig") {
return("red")
}
else if(reactiveData$shapeState=="poly_dest") {
return("green")
}
})
createConnections <- reactive({
reactiveData$connections<-0
df.pois <- data.frame(lat=numeric(),lon=numeric())
data <- mydata()
allData <- data.frame(orig_lat=numeric(),
orig_lon=numeric(),
dest_lat=numeric(),
dest_lon=numeric(),
date=as.Date(character()))
if(nrow(reactiveData$allPoly)>0){
df.pois<-rbind(data.frame(lat=data$orig_lat, lon=data$orig_lon),
data.frame(lat=data$dest_lat, lon=data$dest_lon))
my_poly <- reactiveData$allPoly
pois <- SpatialPoints(df.pois)
poiPoly <- SpatialPolygons(list(Polygons(list(
Polygon(cbind(my_poly$lat, my_poly$lon))
), ID = "x11")))
coords<-as.data.frame(pois[poiPoly])
if(nrow(coords)>0){
allData1<-subset(data,((data$orig_lat %in% coords$lat)))
allData1<-subset(allData1,((allData1$orig_lon %in% coords$lon)))
allData2<-subset(data,((data$dest_lat %in% coords$lat)))
allData2<-subset(allData2,((allData2$dest_lon %in% coords$lon)))
allData<-rbind(allData1,allData2)
}
}else {
if(nrow(reactiveData$origPoly)>0){
df.pois<-data.frame(lat=data$orig_lat, lon=data$orig_lon)
my_poly <- reactiveData$origPoly
pois <- SpatialPoints(df.pois)
poiPoly <- SpatialPolygons(list(Polygons(list(
Polygon(cbind(my_poly$lat, my_poly$lon))
), ID = "x11")))
coords<-as.data.frame(pois[poiPoly])
allData1<-subset(data,((data$orig_lat %in% coords$lat)))
allData1<-subset(allData1,((allData1$orig_lon %in% coords$lon)))
allData<-allData1
data<-allData
}
if(nrow(reactiveData$destPoly)>0){
df.pois<-data.frame(lat=data$dest_lat, lon=data$dest_lon)
my_poly <- reactiveData$destPoly
pois <- SpatialPoints(df.pois)
poiPoly <- SpatialPolygons(list(Polygons(list(
Polygon(cbind(my_poly$lat, my_poly$lon))
), ID = "x11")))
coords<-as.data.frame(pois[poiPoly])
total <- mydata()
allData2<-subset(data,((data$dest_lat %in% coords$lat)))
allData2<-subset(allData2,((allData2$dest_lon %in% coords$lon)))
allData<-allData2
}
}
leafletProxy("map",session = session) %>%
clearGroup("polyconnections")
leafletProxy("map",session = session) %>%
hideGroup("Origins") %>%
hideGroup("Destinations") %>%
clearGroup("tempmarkers")
if(nrow(allData)>0){
reactiveData$connections<-nrow(allData)
leafletProxy("map",session = session,data=allData) %>%
addMarkers(
lng=~dest_lon,
lat=~dest_lat,
icon = uix.destMarker,
group = "tempmarkers"
) %>%
addMarkers(
lng=~orig_lon,
lat=~orig_lat,
icon = uix.origMarker,
group = "tempmarkers"
)
for(i in 1:nrow(allData)) {
row <- allData[i,]
leafletProxy("map",session = session) %>%
addPolygons(lat=c(row$orig_lat,row$dest_lat),lng=c(row$orig_lon,row$dest_lon),group="polyconnections",weight=1)
}
}
})
observeEvent(input$map_marker_click, {
my_poly <- data.frame(lat=numeric(),lon=numeric())
if (nrow(reactiveData$markers) >= 4) {
my_poly <- rbind(my_poly,reactiveData$markers)
if(reactiveData$shapeState=="poly_all") {
reactiveData$allPoly <- rbind(reactiveData$allPoly,my_poly)
}
else if(reactiveData$shapeState=="poly_orig") {
reactiveData$destPoly <- rbind(reactiveData$destPoly,my_poly)
reactiveData$shapeState = "poly_dest"
}
else if(reactiveData$shapeState=="poly_dest") {
reactiveData$origPoly <- rbind(reactiveData$origPoly,my_poly)
reactiveData$shapeState = "poly_orig"
}
leafletProxy('map') %>% # use the proxy to save computation
addPolygons(lat = my_poly$lat, lng = my_poly$lon, group="polygon",color = polyColor(),fillColor=polyColor())
createConnections()
reactiveData$markers <- data.frame(lat=numeric(),lon=numeric())
}
})
}
shinyApp(ui, server)
I don't think that a dataset of 10.000 pairs is "large" for statistics and I'm pretty sure R is designed well enough to handle this amount of data, so I guess it's leaflet itself or my faulty usage of leaflet or reactive data.
I'm also not very sure about the creation of the lines between origins and destinations which also takes a lot of time but I could not find an easier method to draw a simple line between two points on leaflet.
for(i in 1:nrow(conn.data)) {
row <- conn.data[i,]
leafletProxy("map",session = session) %>% addPolygons(lat=c(row$orig_lat,row$dest_lat),lng=c(row$orig_lon,row$dest_lon),group="Connections",weight=0.5)
}

Shiny error oon function

I have been strugling for hours to find out what's worng with my shiny app. The server and ui are below, as well as the function that makes the prediction for the server.
As I write in the text box the reactiveness does work, but the same error appears. I am not an expert in Shiny. This is my second app.
When I run it I get below app (image):
Please help.
Function:
library(tidyr)
library(dplyr)
library(quanteda)
library(stringr)
## Read-in frequencies
df1 <- readRDS("./App/nextword/g1.rds")
df2 <- readRDS("./App/nextword/g2.rds")
df3 <- readRDS("./App/nextword/g3.rds")
df4 <- readRDS("./App/nextword/g4.rds")
texti <- "i, Don't think"
texti <- corpus(texti)
texti <- corpus(tolower(texti))
## Clean input
texti <- tokenize(texti,
remove_numbers = TRUE,
remove_punct = TRUE,
remove_symbols = TRUE,
remove_separators = TRUE,
remove_twitter = TRUE,
remove_hyphens = TRUE,
remove_url = TRUE,
concatenator = " ",
verbose = FALSE)
texti <- dfm(texti)
texti <- data.frame(word = featnames(texti), row.names = NULL, stringsAsFactors = FALSE)
p <- function(texti) {
if(texti[1, ] == "" & texti[2, ] == "" & texti[3, ] == "") {
prediction = df1 %>%
select(word, Frequency)
} else if(texti[1, ] %in% df4$w1 & texti[2, ] %in% df4$w2 & texti[3, ] %in% df4$w2) {
prediction = df4 %>%
filter(w1 %in% texti[1, ] & w2 %in% texti[2, ] & w3 %in% texti[3, ]) %>%
select(w4, Frequency)
} else if(texti[1, ] %in% df3$w1 & texti[2, ] %in% df3$w2) {
prediction = df3 %>%
filter(w1 %in% texti[1, ] & w2 %in% texti[2, ]) %>%
select(w3, Frequency)
} else if(texti[1, ] %in% df2$w1) {
prediction = df2 %>%
filter(w1 %in% texti[1, ]) %>%
select(w2, Frequency)
} else{
prediction = df1 %>%
select(word, Frequency)
}
return(prediction)
}
server:
library(shiny)
library(shinythemes)
library(markdown)
shinyServer(function(input, output, session) {
pt1 <- reactive(p(input$texti)[1])
output$texti1 <- pt1
observeEvent(input$b1, {
updateTextInput(session, "texti",
value = paste(input$texti, pt1()))
})
pt2 <- reactive(p(input$texti)[2])
output$texti2 <- pt2
observeEvent(input$b2, {
updateTextInput(session, "texti",
value = paste(input$texti, pt2()))
})
pt3 <- reactive(p(input$texti)[3])
output$texti3 <- pt3
observeEvent(input$b3, {
updateTextInput(session, "texti",
value = paste(input$texti, pt3()))
})
})
ui:
library(shinythemes)
shinyUI(fluidPage(
theme = shinytheme("darkly"),
tags$hr(),
titlePanel("Next Word Prediction Application"),
tags$hr(),
mainPanel(tabsetPanel(
tabPanel("Prediction",
sidebarLayout(
sidebarPanel(
width = 3,
tags$p(""),
tags$h5("Predicted next word:"),
flowLayout(
actionButton("b1", label = textOutput("texti1")),
actionButton("b2", label = textOutput("texti2")),
actionButton("b3", label = textOutput("texti3"))
)
),
mainPanel(
tags$p(""),
tags$h5("Please, enter your text:"),
h4(tags$textarea(id = "texti", rows = 1, cols = 30, "")))
)),
tabPanel("About", includeMarkdown("README.md"))
))
))

Resources