I'm not familiar with the BatchGetSymbols
package, but the concepts in the example below should be applicable for your use case as well.
First things first, for lack of an elegant way to say this, I'm pretty sure the expression...
stock_info()$return <- reactive({
rep(0, length(stock_info()$ref.date))
})
...just isn't really how shiny
reactive objects and the associated syntax work.
It looks like you could simplify your code a lot by condensing a bunch of your intermediate steps into a single expression. If you only have one set of reactive data you will use in all of your outputs, this might be a more straight forward approach.
library(shiny)
ui <- fluidPage(
textInput('stock','stock',"GE"),
sliderInput('length', 'length', min = 1, max = 10, value = 5),
dataTableOutput('my_table')
)
server <- function(input, output, session) {
## This will update whenever either input$length or input$stock change
stock_info <- reactive({
length <- as.integer(input$length)
temp_stock_info <- data.frame(stock = input$stock,
foo = seq_len(length),
bar = rnorm(length))
temp_stock_info$baz <- paste("xxx",length)
return(temp_stock_info)
})
## Return an output
output$my_table <- renderDataTable({
stock_info()
})
}
shinyApp(ui, server)
However, if you are using the intermediate object l.out
for a variety of end outputs, it might make sense to make it a reactive object of it's own. Then, we can update l.out
whenever a relevant input changes, and then use that intermediate variable to cascade updates through the other downstream reactives.
In addition, we can update downstream reactive objects like stock_info
based on other conditions that don't affect l.out
without re-running l.out
every time.
library(shiny)
ui <- fluidPage(
textInput('stock','stock',"GE"),
sliderInput('length', 'length', min = 1, max = 100, value = 50),
sliderInput('displayLength', 'displayLength', min = 1, max = 20, value = 5),
dataTableOutput('my_table')
)
server <- function(input, output, session) {
## l.out will change with input$length and input$stock
## but NOT input$displayLength
l.out <- reactive({
data.frame(stock = input$stock,
foo = rnorm(input$length),
l.out_update_time = Sys.time())
})
## stock_info will update whenever l.out changes or the displayLength changes.
## l.out will NOT be updated if only input$displayLength changes
stock_info <- reactive({
tmp_stock_info <- head(x = l.out(), n = input$displayLength)
tmp_stock_info$stock_info_update_time <- Sys.time()
return(tmp_stock_info)
})
## Return an output
output$my_table <- renderDataTable({
stock_info()
})
}
shinyApp(ui, server)
library(shiny)
,library(BatchGetSymbols)
, etc.. Exampleui
would ideally only haveinput$stock
,input$length
(with working default values), and a table output printing your desired result dataframe,stock_info
. Exampleserver
code you have is sufficient (even though it doesn't work). Here's a gist of what it might look like – Matt Summersgill