I'm trying to make a shiny app to load some data from different API, to do directly some analysis like graph...
I searched on the website of shiny i didn't find a way. My data doesn't want to load on the graph, i think it's because i load data directly on the server page, because i want load only the data wanted... The data comes from the ecb package from european central bank, which load the data from their API. This my code :
UI
library(shiny)
#library(quantmod)
library(lubridate)
library(plotly)
library(ggplot2)
ti<-c("PIB","MM_M3","Taux_d_Inflation")
data<-data.frame("ICP.M.U2.N.000000.4.ANR","BSI.M.U2.Y.V.M30.X.I.U2.2300.Z01.A","MNA.Q.Y.I8.W2.S1.S1.B.B1GQ._Z._Z._Z.EUR.LR.GY")
colnames(data)<-ti
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel("Evolution Economique"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
h1("Indicateur Europe"),
selectInput("chiffre","Indicateur:",
choice=ti),
#downloadButton("downloadData", "Download"),
actionButton("go","Load"),
hr(),
helpText("Donnees Banque Centrale Europeenne")
),
# Show a plot of the generated distribution
mainPanel(
plotlyOutput("graph")
)
)
))
Server
library(shiny)
library(lubridate)
library(plotly)
library(ggplot2)
library(ecb)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
observeEvent(input[["go"]],handlerExpr = {
compa<-input$chiffre
compa<-as.character(compa)
temp<-data[[compa]]
temp<-as.character(temp)
temp<-data.frame(Date=ymd(as.character(get_data(temp)$obstime),"%Y-%m"),Valeur=get_data(temp)$obsvalue)
temp<-get_data(temp)
temp<-data.frame(Date=temp$obstime,Valeur=temp$obsvalue)
temp
})
output$graph <- renderPlotly({
plot_ly(temp,x=~Date,
y=~Valeur,type="scatter",mode="lines")
#layout(title="Quaterly evolution")
})
})
Your graph isnt aware of the temp object as its initiated locally within the observeEvent, try to use eventReactive instead:
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
temp <- eventReactive(input$go,{
req(input$chiffre)
compa<-input$chiffre
compa<-as.character(compa)
temp<-data[[compa]]
temp<-as.character(temp)
temp<-data.frame(Date=ymd(as.character(get_data(temp)$obstime),"%Y-%m"),Valeur=get_data(temp)$obsvalue)
temp<-get_data(temp)
temp<-data.frame(Date=temp$obstime,Valeur=temp$obsvalue)
temp
})
output$graph <- renderPlotly({
plot_ly(temp(),x=~Date,y=~Valeur,type="scatter",mode="lines")
#layout(title="Quaterly evolution")
})
})
Related
I have an AWS bucket with a bunch of dynamically generated JSON files. When a file is generated it gets a "slug".
I'd like to be able to copy that slug (from an outside website) and enter it in a Shiny textInput box, then add the rest of the URL to the slug, and download the designated file as an R object. (I use jsonlite::fromJSON here).
The code below works, and it generates the correct string and puts it into a box in the ui side. But I can't figure out how to use that output variable on the server side. It is hard-coding the "slug". I want to use the slug from the ui textInput.
library(tidyverse)
library(igraph)
library(jsonlite)
library(circlize)
library(chorddiag)
library(plotly)
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(title = ""),
dashboardSidebar(
textInput("slug","Discovery ID",placeholder = "N79og8K"),
fluidRow(box(textOutput("URL")))
)
)
server <- function(input, output) {
# raw_data_URL <- "https://XXX.s3.us-west-1.amazonaws.com"
# raw_data_suffix <- ".json"
#
# full_URL <- eventReactive(input$submit, {
# paste0(raw_data_URL,"/",input$slug,raw_data_suffix)
# })
# output$URL <- renderPrint(full_URL())
data <- fromJSON(paste0(raw_data_URL,"/","N79og8K",raw_data_suffix))
)
}
I've tried all sorts of things with reactive objects, and haven't gotten anything to work.
Also, the commented out text does work too: it populates the box with the right string on "submit". But I can't get the server to go to the resulting file URL.
Can I use the output variable in my server app?
The following app will prepare the URL, fetch it, and then modify it in the server. It will print the output at each step.
library(tidyverse)
library(shiny)
library(jsonlite)
ui <- fluidPage(
textInput("slug","Type in Name",value = "charlie"),
actionButton("submit", "Submit"),
textOutput("URL"),
textOutput("raw_JSON"),
textOutput("modified_JSON")
)
server <- function(input, output) {
raw_data_URL <- "https://api.genderize.io/?name="
full_URL <- eventReactive(input$submit, {
paste0(raw_data_URL,input$slug)
})
output$URL <- renderPrint(full_URL())
full_JSON <- reactive({
fromJSON(full_URL())
})
output$raw_JSON <- renderPrint(full_JSON())
JSON <- reactive({
full_JSON()$probability
})
output$modified_JSON <- renderPrint(JSON())
}
shinyApp(ui = ui, server = server)
I removed the shinydashboard package to make the solution more minimal. Not every Shiny developer has or knows it.
The key point is that when you want to use something reactive, you have to treat it like a function and put () after it, like I did for full_URL(), full_JSON() and JSON() above. Also, you can only use reactive objects inside of other reactives like reactive() and renderPrint().
Here's a minimal reprex of what actually ended up working
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(tidyverse)
library(jsonlite)
library(igraph)
library(plotly)
library(chorddiag)
ui = dashboardPage(
dashboardHeader(),
dashboardSidebar(fluidRow(textInput("slug", "Discovery ID",value = "VJPEqQB")),
actionButton("submit", "Submit")),
dashboardBody()
),
server = function(input, output, session) {
raw_data_URL <- "https://XXX-bucket.s3.us-west-1.amazonaws.com"
raw_data_suffix <- "_graph.json"
saveData <- function(data) {
set.seed(1)
data <- fromJSON(data)
}
# Construct the URL
getURL <- reactive({
data <- paste0(raw_data_URL,"/",input$slug,raw_data_suffix)
data
})
# When the Submit button is clicked:
observeEvent(input$submit, {
saveData(getURL())
})
# Show Outputs (omitted from MRE)
# Not Used:
output$graph <- renderPlot({
input$submit
plot(net) # net is a graph object derived from `data`
})
}
)
I am baffled why the following code produces the "Shiny.setInputValue is not a function" error:
library(shiny)
library(htmltools)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Test"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
),
# Show a plot of the generated distribution
mainPanel(
shiny::tags$script(htmltools::HTML('
quantityaa = 1;
console.log(quantityaa);
Shiny.setInputValue("hi", quantityaa);
'))
,
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
hi <- reactive({ input$hi})
print(hi)
}
# Run the application
shinyApp(ui = ui, server = server)
What is wrong with this code that produces this error? I cannot see anything wrong with it, but I must be missing something.
That's because Shiny is not ready yet. Use the shiny:connected event:
$(document).on("shiny:connected", function() {
// your awesome JavaScript here can use Shiny.setInputValue
});
When using a range slider in a shiny app, can you require a minimum range of selected values? I am using the sliderTextInput() function in the shinyWidgets package, but think this is general to range sliders. Toy example code:
testx=1:150
testy=1:150
library(shiny) # also requires shinyWidgets package be installed
ui <- fluidPage(
plotOutput("plot"),
shinyWidgets::sliderTextInput("range","Input Size:",
choices=c(1,25,50,100),
selected=c(25,50), grid = T)
)
server <- function(input, output) {
output$plot <- renderPlot({
plot(testx[input$range[1]:input$range[2]],testy[input$range[1]:input$range[2]],
xlim=c(0,150),ylim=c(0,150))
})
}
shinyApp(ui, server)
The issue I am trying to avoid is the one below, where both ends of a slider are set to the same value, which results in a single point being plotted--I'd like to require a range be selected.
You can update the values if the are the same:
testx=1:150
testy=1:150
library(shiny) # also requires shinyWidgets package be installed
library(shinyWidgets)
ui <- fluidPage(
plotOutput("plot"),
sliderTextInput("range","Input Size:",choices=sliderchoice,selected=c(25,50), grid = T)
)
server <- function(input, output,session) {
observeEvent(input$range,{
if(input$range[1] == input$range[2]){
updateSliderTextInput(session,"range",selected = c((input$range[1]-1),input$range[2]))
}
})
output$plot <- renderPlot({
plot(testx[input$range[1]:input$range[2]],testy[input$range[1]:input$range[2]],
xlim=c(0,150),ylim=c(0,150))
})
}
shinyApp(ui, server)
I would like to make a plotly graph on shiny, very simple... but i don't get it... it's a candlestick graph... I load data from yahoo finance, i put it in a list and i create a dataframe following what we want see... but it doesn't work, it load all except the graph with the sentence :
"First argument, data, must be a data frame or shared data"
library(shiny)
library(quantmod)
library(lubridate)
library(plotly)
library(dplyr)
trim<-Sys.Date()- months(3)
#floor_date(ajd,"month")
comp<-c("CAC 40","Total","Sanofi","BNP","LVMH","Airbus","Axa","L'Oreal","Air Liquide","Danone","Vinci","Schneider","Societe Generale","Kering","Orange")
ref<-data.frame("^FCHI","FP.PA","SAN.PA","BNP.PA","MC.PA","AIR.PA","CS.PA","OR.PA","AI.PA","BN.PA","DG.PA","SU.PA","GLE.PA","KER.PA","ORA.PA")
colnames(ref)<-comp
for (i in 1:length(comp)){
stock<-ref[1,i]
stock<-as.character(stock)
getSymbols(stock,src="yahoo",from=trim,to=Sys.Date())
}
for (i in 1:length(comp)){
ref[,i]<-as.character(ref[,i])
}
ref[,1]<-c("FCHI")
data<-list()
for (i in 1:length(comp)){
data[[i]]<-get(ref[,i])
}
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel("Top companies of CAC 40 Analysis"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
h1("Companies"),
selectInput("titre","Company:",
choice=colnames(ref)),
hr(),
helpText("Data from yahoo finance")
),
# Show a plot of the generated distribution
mainPanel(
h3("Evolution du cours"),
plotlyOutput("graph")
)
)
))
library(shiny)
library(quantmod)
library(lubridate)
library(plotly)
library(dplyr)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
sortie<-reactive({
compa<-input$titre
temp<-data.frame(Date=index(data[[compa]]),coredata(data[[compa]]))
colnames(temp)<-c("Date","Open","High","Low","Close","Volume","Adjusted")
})
output$graph <- renderPlotly({
plot_ly(sortie,x=sortie$Date,type="candlestick",
open=sortie$Open,close=sortie$Close,high=sortie$High,low=sortie$Low)
layout(title="Quaterly evolution")
})
})
If someone find something i made wrong...
Hi there wasa a couple of problems with your code
first the data was not a named list so I changed the line
temp<-data.frame(Date=index(data[[compa]]),coredata(data[[compa]]))
to
temp<-data.frame(Date=index(data[[which(compa == comp)]]),coredata(data[[which(compa == comp) ]]))
to get the right index of comnp
then you were not returning the data frame from sortie but rather the vector of the column names. I just added a call to temp at the end of sortie to fix this. The last thing Ryan already mentioned in his comment with the brackets after sortie. Below follows a working version of the server code. I haven't changed anything else.
function(input, output) {
Sortie<-reactive({
compa<-input$titre
temp<-data.frame(Date=index(data[[which(compa == comp)]]),coredata(data[[which(compa == comp) ]]))
colnames(temp)<-c("Date","Open","High","Low","Close","Volume","Adjusted")
temp
})
output$graph <- renderPlotly({
sortie <- Sortie()
plot_ly(sortie,x=sortie$Date,type="candlestick",
open=sortie$Open,close=sortie$Close,high=sortie$High,low=sortie$Low) %>%
layout(title="Quaterly evolution")
})
}
It was that but i added the names of companies in the list in ui code :
data<-list()
for (i in 1:length(comp)){
data[[i]]<-get(ref[,i])
}
names(data)<-comp
So after my original code works with that :
shinyServer(function(input, output) {
sortie<-reactive({
compa<-input$titre
temp<-data.frame(Date=index(data[[compa]]),coredata(data[[compa ]]))
colnames(temp)<-c("Date","Open","High","Low","Close","Volume","Adjusted")
temp
})
output$graph <- renderPlotly({
sortie<-sortie()
plot_ly(sortie,x=~Date,type="candlestick",
open=~Open,close=~Close,high=~High,low=~Low)%>%
layout(title="Quarterly evolution")
})
})
I am trying to build a simple Shiny App, but cant get it to work. I want to select a state and then the app should calculate the mean of that state for sample.measurement of ozone level. Here is my ui.R code:
require(shiny)
fluidPage(pageWithSidebar(
headerPanel("Ozone Pollution"),
sidebarPanel(
h3('State'),selectInput("inputstate","Select State",state.name)),
mainPanel(
h3('Results'),verbatimTextOutput("res")
)
))
And here is my server.R program:
require(dplyr)
library(shiny)
shinyServer(
function(input, output) {
stat_state<-reactive({filter(ozone_2015,State.Name==input$inputstate)})
output$res<- renderPrint({mean(stat_state$Sample.Measurement)})
}
)
Any Hints? Thanks.....
While I can't replicate your dataset because I don't know where ozone_2015 comes from, I think your problem is that you're not referring to "reactive" objects like this:
stat_state()
Once you make a reactive object, with the exception of reactive values and input$ variables, you need to refer to it with '()' at the end of the variable.
Here is an example using some of your code with a different dataset. Hope this helps.
require(shiny)
ui <-
fluidPage(pageWithSidebar(
headerPanel("Population"),
sidebarPanel(
h3('State'),selectInput("inputstate","Select State",state.name)),
mainPanel(
h3('Results'),verbatimTextOutput("res")
)
))
server <- function(input,output){
require(dplyr)
sample.data <- reactive({as.data.frame(state.x77)})
stat_state <- reactive({sample.data()[which(row.names(sample.data()) == input$inputstate),]})
output$res <- renderPrint({stat_state()$Population})
}
)
}
shinyApp(ui = ui, server = server)