Im trying to create a web application with the new RStudio feature Shiny, which plots different stocks. I created the following example.
I want to select the dataset StockMarket then select eg the DAX and then finally the plot should appear.
Right now if you run this code the plot appears immediately
Could you help me please?
ui.R:
library(shiny)
library(ggplot2)
shinyUI(pageWithSidebar(
# Application title
headerPanel("Plot1"),
sidebarPanel(
selectInput("dataset", "Dataset", list("mtcars"="cars", "StockMarket"="stocks")),
conditionalPanel(
condition = "input.dataset=='stocks'",
uiOutput("data")
)),
mainPanel(
plotOutput('plotstock')) ))
server.R:
library(shiny)
require(ggplot2)
library(datasets)
shinyServer(function(input, output) {
output$data<- reactiveUI(function() {
selectInput("data", "Choose Dataset", colnames(EuStockMarkets))
})
output$plotstock <- reactivePlot(function() {
data<-data.frame(EuStockMarkets)
p<- ggplot(data,aes(x=seq(1,length(data[,1])),y=DAX))+geom_line(size=1)+ylab("")+opts(title="Time Series")
print(p)
})})
In the reactivePlot function you can do something like
if (is.null(input$data))
return(NULL)
I would also add a blank entry to the dataset choices ("(Choose one)"="") and also have
if (!nzchar(input$dataset))
return(NULL)
in reactivePlot.
Also make sure that you check for empty strings
if (!nzchar(input$dataset) || input$dataset=='')
return(NULL)
Related
I need your help, because I don't know how to solve my problem. I have my shiny app where I have data frame (imported from file) and checkboxgroupinput where I can mark which columns are for me interesting. After that in other tabpanel I would like to get two plot for each column (in one facet_wrap). All facet_wrap one under the other. The problem is that number of interesting columns is not constant. It is easy for my if I could hardcode number of rows with plots, but where it can change dynamically I have no idea how to program it, any tips from your side?
We can't solve your question without a reproducible example but you should be able to figure it out from this quick example of using uiOutput along with renderUI. This allows the use of dynamic values in UI elements.
Normally you would define your static input as checkboxGroupInput("columns", "Select the variables to plot", choices = vector_of_known_values).
However as per your question, this doesn't work if the dataset is not known beforehand (e.g.: user file upload). In this case use uiOutput in the UI part: uiOutput("ui"), so that you delay evaluation to server side. In server side you can dynamically set the choices regardless of the data structure.
output$ui <- renderUI( {
checkboxGroupInput("columns", "Select the variables to plot", choices = colnames(rv$data))
})
See full example:
library(shiny)
library(DT)
library(dplyr)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("datasets", "Select a dataset", choices = c("mtcars", "iris"), selected = "mtcars"),
uiOutput("ui")
),
mainPanel(
DT::dataTableOutput("table")
)
)
)
server <- function(input, output, session) {
rv <- reactiveValues(data = NULL)
observe( {
rv$data <- eval(parse(text = input$datasets))
})
filtered <- reactive( {
req(input$columns)
if( all(!input$columns %in% colnames(rv$data))) {
NULL
} else {
rv$data %>% select(input$columns)
}
})
output$ui <- renderUI( {
checkboxGroupInput("columns", "Select the variables to plot", choices = colnames(rv$data))
})
output$table <- DT::renderDataTable( {
req(filtered())
DT::datatable(filtered())
})
}
shinyApp(ui, server)
I'm trying to generate a list in a selectInput, dynamically. I have a sidebarPanel in which I have declared a tabsetPanel. Each tabsetPanel will have different outputs, all of which I want to display in the sidebar. So the output of the first tab would be a selectInput or perhaps 2 selectInputs, while the same would go for the second tab.
Here is my sidebarPanel code in ui.R
## ui.R
sidebarPanel(
tabsetPanel(
tabPanel("aZ", uiOutput("aToZPlayerList")),
tabPanel("byTeam", uiOutput("byTeamPlayerList"))
),
),.......
In server.R, I have written the following:
## server.R
output$aToZPlayerList <- renderUI({
selectInput("alphabet", "Players A-Z", choices=aToZ, selected=0)
htmlOutput("List")
})
output$byTeamPlayerList <- renderUI({
selectInput("team", "Teams", choices=teamList, selected=0)
htmlOutput("List")
})
But this does not work, as nothing is rendered in the sidebarPanel. I feel like I'm missing something, but as I'm quite new to this, I still haven't figured it out.
I haven't been able to find an answer on here or elsewhere as of yet. Any help please? Thanks.
You should not have two widgets under one uiOutput, i would recommend to separate it:
## ui.R
sidebarPanel(
tabsetPanel(
tabPanel("aZ", uiOutput("aToZPlayerList"), htmlOutput("List")),...
## server.R
output$aToZPlayerList <- renderUI({
selectInput("alphabet", "Players A-Z", choices=aToZ, selected=0)
})...
and it will work.
[FULL EXAMPLE]
library(shiny)
fruits <- c("banana","raccoon","duck","grapefruit")
ui <- pageWithSidebar(
# Application title
headerPanel("Hello Shiny!"),
# Sidebar with a slider input
sidebarPanel(
tabsetPanel(
tabPanel("aZ", uiOutput("aToZPlayerList"), htmlOutput("List")),
tabPanel("byTeam", uiOutput("byTeamPlayerList"))
)),
# Show a plot of the generated distribution
mainPanel()
)
server <- function(input,output){
output$aToZPlayerList <- renderUI({
selectInput("alphabet", "Players A-Z", choices=c("A","B","C"), selected="A")
})
output$List <- renderUI({
HTML(paste(fruits))
})
output$byTeamPlayerList <- renderUI({
selectInput("team", "Teams", choices=c("A","B","C"), selected="B")})
}
runApp(list(ui=ui,server=server))
I have a shiny code like in the below. I need to define variables as reactiveValues to be updatable (or I could define them I think as global but then I have to press clean objects from Rstudio which is not very user-friendly).I try to run a validate code to check for existence of the data I have defined as reactiveValues. validate(need(exists("GSEmRNA$d"),message="Dataframe not found")) yields "Dataframe not found" thus, does not plot my boxplot. If I define them as global variables and forget to press clean objects, code might mix up as old data can be passed as if it is new. Any help is appreciated.
server.R
shinyServer(function(input, output) {
observeEvent(input$GoButton,{
dataset <- data.frame(first= c(1,5,9),second=c(8,5,13), third=c(10,3,17))
GSEmRNA <- reactiveValues(d=dataset)
})
output$BoxplotDataset <- renderPlot({
if (input$GoButton== 0) {return()}
else{
validate(need(exists("GSEmRNA$d"),message="Dataframe not found"))
boxplot(GSEmRNA$d)}
})
})
ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Dataset Selection"),
sidebarPanel(
actionButton("GoButton","GO")
),
mainPanel(
wellPanel(
column(8, plotOutput("BoxplotDataset")
)
)
)))
FOR THE RECORD, I ALSO POSTED THIS QUESTION TO SHINY GOOGLE DISCUSS GROUP https://groups.google.com/forum/#!topic/shiny-discuss/ZV5F6Yy-kFg
Here are the updated code. The points are:
library(shiny)
server <-shinyServer(function(input, output) {
GSEmRNA <- reactiveValues(d=NULL) #define it ouside
observeEvent(input$GoButton,{
dataset <- data.frame(first= c(1,5,9),second=c(8,5,13), third=c(10,3,17))
GSEmRNA$d <- dataset #assign it inside
})
output$BoxplotDataset <- renderPlot({
validate(need(GSEmRNA$d,"Dataframe not found")) # changed as well
boxplot(GSEmRNA$d)
})
})
ui <- pageWithSidebar(
headerPanel("Dataset Selection"),
sidebarPanel(
actionButton("GoButton","GO")
),
mainPanel(
wellPanel(
column(8, plotOutput("BoxplotDataset")
)
)
))
runApp(list(ui=ui,server=server))
Defined the reactiveValues outside of the observeEvent
Changed the reactiveValues inside of the observeEvent
Changed the validate and need.
If I have the following data frame:
Hours<-c(2,3,4,2,1,1,3)
Project<-c("a","b","b","a","a","b","a")
cd=data.frame(Project,Hours)
What is wrong with the following Shiny code:
Why do I get the error:Error in tag("form", list(...)) : argument is missing, with no default
Server.R
##server.R
library(shiny)
library(ggplot2)
library(lattice)
# Define shiny server
shinyServer(function(input, output) {
#Simple test plot
output$testPlot = renderPlot( {
pdata=subset(cd, Project==input$proj)
densityplot(pdata$Hours,lwd=3)
})
})
ui.R
library(shiny)
ulist=levels(cd$Project)
names(ulist) = ulist
# Sidebar with a slider input for the number of bins
shinyUI(pageWithSidebar(
# Application title
headerPanel("Project Data"),
sidebarPanel(
#Which table do you want to view, based on the list of institution names?
selectInput("proj", "Project:",ulist),
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("testPlot"),
)
)
)
The error again is: Error in tag("form", list(...)) : argument is missing, with no default
This seems so simple but I don't know what's wrong. Any advice would be most appreciated.
You have superfluous comma's in your ui.R:
shinyUI(pageWithSidebar(
headerPanel("Project Data"),
sidebarPanel(
selectInput("proj", "Project:",ulist) # remove comma here
),
mainPanel(
plotOutput("testPlot") # remove comma here
)
) )
I think you have a couple of extra commas in the ui.R, namely after the selectInput and plotOutput commands
I build an R/shiny web app. I want to have a multiple choice box (I use checkboxGroupInput(), but am open to alternatives). However, the list of choices is long and I want to contain it in a relatively small box of options (that shows 5-6 options at a time) with a scroll bar that enables to scroll through the entire list of choices.
Is there a way this can be done?
minimal example:
ui.R
library(shiny)
choices = paste("A",1:30,sep="_")
shinyUI(pageWithSidebar(
# Application title
headerPanel("my title"),
sidebarPanel(
checkboxGroupInput("inp", "choose any of the following", choices)
),
mainPanel(
tableOutput("result")
)
))
server.R
library(shiny)
shinyServer(function(input, output) {
myInput <- reactive({
input$inp
})
output$result <- renderTable({
x = myInput()
if(length(x)==0) {
x = "No Choice Made"
}
matrix(x,ncol=1)
})
})
I found that using selectInput(..., multiple = TRUE) does the trick.