Shiny app: Can't plot stock chart based on user input - r

I am trying to plot a stock chart using quantmod in a shiny app but I get the following error: input$stockInput download failed after two attempts. Error message: HTTP error 404. Any help is appreciated.
Server:
library(quantmod)
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
price <- getSymbols('input$stockInput',from='2017-01-01')
plot(price)
})})
UI:
library(shiny)
shinyUI(fluidPage(
titlePanel("Stock Chart"),
sidebarLayout(
sidebarPanel(
#This is a dropdown to select the stock
selectInput("stockInput",
"Pick your stock:",
c("AMZN","FB","GOOG","NVDA","AAPL"),
"AMZN"),selected = "GOOG"),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
))))
Thank you.

Your code requires a few changes. First when you are accessing a shiny UI object in server.R you should use it as an object not as a quoted character
price <- getSymbols(input$stockInput,from='2017-01-01')
And the function getSymbols without a value set to the argument (auto.assign = F) creates a new xts object in the stock name whose data is requested and so in the below code I've used it with setting auto.assign = F so it becomes easier to access the object price for plotting. Otherwise, you might have to fetch the value inside price using get() and then plot them as I've commented.
server.R
library(quantmod)
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
price <- getSymbols(input$stockInput,from='2017-01-01', auto.assign = F)
#plot(get(price), main = price) #this is used when auto.assign is not set by default which is TRUE
plot(price, main = input$stockInput) # this is when the xts object is stored in the name price itself
})})
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Stock Chart"),
sidebarLayout(
sidebarPanel(
#This is a dropdown to select the stock
selectInput("stockInput",
"Pick your stock:",
c("AMZN","FB","GOOG","NVDA","AAPL"),
"AMZN"),selected = "GOOG"),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
))))
Hope it clarifies!

Related

How to render the shiny's output via plumber/REST API to other programmers?

Hey Shiny and Plumber experts,
Relevant links :
https://abndistro.com/post/2019/07/06/deploying-a-plumber-api-on-aws-ec2-instance/
https://abndistro.com/post/2019/07/06/deploying-a-shiny-app-with-shiny-server-on-an-aws-ec2-instance/
Basically, we are trying to pass the output of shiny via Plumber to other programmers to integrate in an webpage.
From the documentation, running on local machine,
following works individually:
Plumber reprex
#* Plot a histogram
#* #png
#* #get /plot
function(){
random_num <- rnorm(10) * 5
hist(random_num)
}
saving the file as plumber.R
# Running the below in console
r <- plumb("plumber.R") # Where 'plumber.R' is the location of the file shown above
r$run(port=8000)
# Now, loading the browser: http://127.0.0.1:8000/__swagger__/
[![plumber output][1]][1]
Similarly shiny reprex :
library(shiny)
# Define UI for application that plots random distributions
ui = shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# Sidebar with a slider input for number of observations
sidebarLayout(
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min = 1,
max = 1000,
value = 500)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
# Define server logic required to generate and plot a random distribution
server = shinyServer(function(input, output) {
# Expression that generates a plot of the distribution. The expression
# is wrapped in a call to renderPlot to indicate that:
#
# 1) It is "reactive" and therefore should be automatically
# re-executed when inputs change
# 2) Its output type is a plot
output$distPlot <- renderPlot({
# generate an rnorm distribution and plot it
dist <- rnorm(input$obs)
hist(dist)
})
})
# Run the app
shinyApp(ui, server)
How can we render shiny's output i.e histogram into plumber's swagger ?
i.e. How to display the user
Tried: Embedding the plumber function within Shiny's renderFunction
library(shiny)
# Define UI for application that plots random distributions
ui = shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# Sidebar with a slider input for number of observations
sidebarLayout(
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min = 1,
max = 1000,
value = 500)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
# Define server logic required to generate and plot a random distribution
server = shinyServer(function(input, output) {
# Expression that generates a plot of the distribution. The expression
# is wrapped in a call to renderPlot to indicate that:
#
# 1) It is "reactive" and therefore should be automatically
# re-executed when inputs change
# 2) Its output type is a plot
#### Embedding inside the shiny
output$distPlot <- renderPlot({
#* Plot a histogram
#* #png
#* #get /plot
function(){
# generate an rnorm distribution and plot it
dist <- rnorm(input$obs)
hist(dist)
}
})
})
shinyApp(ui, server)

How do I use Crosstalk in Shiny to filter a reactive data table?

I cannot use functions from the Crosstalk package in a Shiny app. When running, I receive an error message saying my SharedData object is not found.
I would like to create a Shiny app where users can filter in various ways (selectInput, selecting rows in a data table, etc.) but all tables, charts and maps update simultaneously regardless of the filter method. I have heard that crosstalk is good for this and I have relied on the volcano example here as a template.
My issue is that when I attempt to run my app, I receive a warning saying that the SharedData object cannot be found. I've tried placing this in the server part, and tried placing within reactive, eventReactive, observe, observeEvent, etc. but these don't make any difference. I've also tried placing the code outside of both ui and server parts but the only difference is that my error is now "object of type 'environment' is not subsettable".
Below is not my original code; I have simplified the issue and made it reproducible by sharing the following:
*Created a new Shiny app from Rstudio (the template uses the faithful dataset)
*Modified the dataset from faithful to iris
*Added a call to the crosstalk library
*Included filter_select, SharedData calls
*Modified line 48 to refer to shared_df rather than iris
library(shiny)
library(crosstalk)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Crosstalk test"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30),
filter_select("rows", "Select rows:",
shared_df,
~Species,
multiple = TRUE)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
# Shared data available for use by the crosstalk package
shared_df <- SharedData$new(iris)
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- shared_df[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
}
# Run the application
shinyApp(ui = ui, server = server)
My expected results should include a histogram chart with interactive slider to dynamically adjust bin widths (as per the "old faithful" template). In addition, I should be able to select Species of plant and the histogram should dynamically update to only display results for the selected Species.
* edit *
I've managed to recreate the volcano example linked to above for a Shiny app. The code below works:
library(shiny)
library(crosstalk)
library(leaflet)
library(DT)
# Wrap data frame in SharedData
# Use SharedData like a dataframe with Crosstalk-enabled widgets
sd <- SharedData$new(quakes[sample(nrow(quakes), 100),])
ui <- fluidPage(
# Create a filter input
filter_slider("mag", "Magnitude", sd, column=~mag, step=0.1, width=250),
bscols(leafletOutput("map"), DTOutput("table"))
)
server <- function(input,output) {
output$map <- renderLeaflet({ leaflet(sd) %>% addTiles() %>% addMarkers()})
output$table <- renderDT({
datatable(sd, extensions="Scroller", style="bootstrap", class="compact", width="100%",
options=list(deferRender=TRUE, scrollY=300, scroller=TRUE))
}, server = FALSE)
}
shinyApp(ui = ui, server = server)
The only difference between this volcano example and my iris example is (apart from moving the shared_df outside of ui and server) the usage of filter_select. When I move shared_df a different error is returned: "Warning: Error in [: object of type 'environment' is not subsettable"

r shiny: Creating widgets in ui.R vs. renderUI + uiOutput

I have a question that falls more into a "best practice" type of inquiry. When using shiny package in r, is it better to create all widgets on the server side using renderUI and then pushing those to the ui via uiOutput? Or, when possible, should all widgets be created on the ui side?
For instance, the two apps below do the same thing but in the second one, I create the sliderInput on the server side and then push that to the ui rather than creating it in the ui side. (Note, this code is pulled from the Hello Shiny page on R Studio)
App 1 - "Standard Approach" creating widget in ui
#ui.R
# Define UI for application that plots random distributions
library(shiny)
ui1 <- shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# Sidebar with a slider input for number of observations
sidebarLayout(
sidebarPanel(
sliderInput("obs",
"Number of observations:",
min = 1,
max = 1000,
value = 500)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
#server.R
# Define server logic required to generate and plot a random distribution
library(shiny)
server1 <- (function(input, output) {
output$distPlot <- renderPlot({
# generate an rnorm distribution and plot it
dist <- rnorm(input$obs)
hist(dist)
})
})
runApp(shinyApp(ui = ui1, server = server1))
App 2 - Alternative Approach - Creating Widget on server side
#ui.R
# Define UI for application that plots random distributions
library(shiny)
ui2 <- shinyUI(fluidPage(
# Application title
titlePanel("Hello Shiny!"),
# slider comes from the si object created in server.R
sidebarLayout(
sidebarPanel(
uiOutput("si")
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
))
#server.R
# Define server logic required to generate and plot a random distribution
library(shiny)
server2 <- (function(input, output) {
#create slider with renderUI
output$si <- renderUI(
sliderInput("obs",
"Number of observations:",
min = 1,
max = 1000,
value = 500)
)
output$distPlot <- renderPlot({
# generate an rnorm distribution and plot it
dist <- rnorm(input$obs)
hist(dist)
})
})
runApp(shinyApp(ui = ui2, server = server2))
To me, the second approach is more generalizable so it should win. However, I am no expert and I rarely see this approach being used unless there is a specific reason why you need the widgets to be responsive in some way. The ways in which I have required responsiveness include:
There is data loaded on the server side which ends up feeding the widget choices so it is better to only load the data one time on the server side and create the widgets there, rather than load it on the server and ui side.
We need to turn off/on widgets and/or allow them to react to other user input
Since the second approach I've presented can handle the above two options, it makes sense to me that it should be used in all cases, even when there is no real need to create the widget on the server side. I notice that when using the second approach, there is a delay, sometimes accompanied by warnings/errors prior to the widgets being loaded. That is the only downside I've noticed about the approach.
Is one of these approaches considered a "best practice?"
Thanks.

R shiny, subscript out of bounds

I'm working with simple Shiny app in R, but I face this error in the app:
subscript out of bounds
The idea is to have a sidebar panel where you can choose vocal or consonant, and a barplot that visualize some letters with some numbers, clearly, choosing a vocal,vocals are with values, and so on with the consonant.
Here my code
First, I create the data:
x1<-c(1,2,6,3,8)
y1<-c('a','b','c','d','e')
z1<-c('V','C','C','C','V')
df<-data.frame(x1,y1,z1)
data.m <- melt(df, id=c(2:3), measure=c(1))
df2<-cast(data.m , z1 ~ y1)
df3<-as.matrix(df2)
Here the server code:
##server
function(input, output) {
output$Plot <- renderPlot({
library(reshape)
barplot(df3[,input$letters])
})
}
and here the ui part
##ui
fluidPage(
titlePanel("letters"),
sidebarLayout(
sidebarPanel(
selectInput("letters", "Letters",
choices=rownames(df3)),
hr(),
helpText("Types of letters")
),
mainPanel(
plotOutput("Plot")
)
)
)
Well the error is the one in the title. Could you help me?
Furthermore, is there any way to put the data into the Shiny app to have them loaded when you start the app?
Thanks a lot in advance

R Shiny Tabsets simultaneous processing

I have a R Shiny app, which calculates several statistics in different tabsets. As the calculations are quite computation intensive, I use submitButton to prevent reactivity. My problem is now that each calculation (all in different tabsets) are writing outputs to a folder and I want Shiny to write an output for all tabsets when initializing. Unfortunately, Shiny only creates an output for the tabset, that is active when initializing. Is there a way to tell Shiny, that it should calculate/render outputs for every tab when initializing?
Here is a modified example from the Shiny[Tutorial]:(http://www.http://rstudio.github.io/shiny/tutorial/#more-widgets/)
ui.R:
library(shiny)
# Define UI for dataset viewer application
shinyUI(pageWithSidebar(
# Application title.
headerPanel("More Widgets"),
# Sidebar with controls to select a dataset and specify the number
# of observations to view. The helpText function is also used to
# include clarifying text. Most notably, the inclusion of a
# submitButton defers the rendering of output until the user
# explicitly clicks the button (rather than doing it immediately
# when inputs change). This is useful if the computations required
# to render output are inordinately time-consuming.
sidebarPanel(
selectInput("dataset", "Choose a dataset:",
choices = c("rock", "pressure", "cars")),
numericInput("obs", "Number of observations to view:", 10),
helpText("Note: while the data view will show only the specified",
"number of observations, the summary will still be based",
"on the full dataset."),
submitButton("Update View")
),
# Show a summary of the dataset and an HTML table with the requested
# number of observations. Note the use of the h4 function to provide
# an additional header above each output section.
mainPanel(
tabsetPanel(
tabPanel("Summary", verbatimTextOutput("summary")),
tabPanel("Table", tableOutput("view"))
)
)
))
server.R:
library(shiny)
library(datasets)
# Define server logic required to summarize and view the selected dataset
shinyServer(function(input, output) {
# Return the requested dataset
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars)
})
# Generate a summary of the dataset
output$summary <- renderPrint({
dataset <- datasetInput()
capture.output(summary(dataset),file="summary.txt")
})
# Show the first "n" observations
output$view <- renderTable({
a<-head(datasetInput(), n = input$obs)
capture.output(a,file="table.txt")
})
})
I think you want:
outputOptions(output, "summary", suspendWhenHidden = FALSE)
outputOptions(output, "view", suspendWhenHidden = FALSE)
Put this into your server.R. Let me (us) know if this works as you expect.
Documentation:
http://www.inside-r.org/packages/cran/shiny/docs/outputOptions

Resources