Reputation: 5660
I have some data as shown in the sample df
below. There are data for 3 US states (CA, TX, NY) plus the Total, and for each of these there is an actual act
, forecast fct
, and predicted pred
value.
I want to create a Shiny app in which the user can select which states to observe on the plot. To do this I'm using checkboxGroupInput
. I have a reactive
function named DF
in the server portion of my code that subsets df
based on user selected states. I then have a reactive
function named gl
that creates all the geom_line()
statements I need to create a ggplot. The reason I'm doing this is because I want to keep the color
the same for each state and use linetype
to distinguish actual, forecast, or predicted for them.
Lastly, I try to create the plot, but this is where the problem begins. I get no error message, but no plot displays when I run the app. Is there a way to fix this, or a better way to accomplish what I want? Below is the code I have and a plot of what I would like to show if the user had selected all states and Total.
library(shiny)
library(ggplot2)
library(scales)
library(lubridate)
df <- data.frame(Date=seq.Date(as.Date('2017-01-01'), as.Date('2017-05-01'), by='month'),
CAact=rnorm(5, 10, 2), TXact=rnorm(5, 10, 2), NYact=rnorm(5, 10, 2),Totalact=rnorm(5, 30, 2),
CAfct=rnorm(5, 10, 2), TXfct=rnorm(5, 10, 2), NYfct=rnorm(5, 10, 2), Totalfct=rnorm(5, 30, 2),
CApred=rnorm(5, 10, 2), TXpred=rnorm(5, 10, 2), NYpred=rnorm(5, 10, 2), Totalpred=rnorm(5, 30, 2)
)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput('states', 'Select Regions',
choices=c('CA','TX','NY','Total'),
selected=c('CA','TX','NY','Total')
)
),
mainPanel(
plotOutput('portfolio')
)
)
)
server <- function(input, output){
#Function to subset df based on user selected states
DF <- reactive({
df <- df[,c('Date', names(df)[grep(paste(input$states, collapse='|'), names(df))])]
return(df)
})
#Generate all the 'geom_line' statements to create ggplot
gl <- reactive({
gl <- character()
lt <- 1
for(i in 2:length(DF())){
col <- substr(names(DF())[i], 1, 2)
if(grepl('Total', names(DF())[i])){
col <- 'Total'
}
if(grepl('fct', names(DF())[i])){
lt <- 5
} else if(grepl('pred', names(DF())[i])){
lt <- 4
}
line <- paste0("geom_line(aes(y=", names(DF())[i], ", color='", col, "'), linetype=", lt, ", size=1.25) + ")
gl <- paste0(gl, line)
}
})
#Create ggplot (not working)
output$portfolio <- renderPlot({
paste0("ggplot(data=DF(), aes(Date)) + ", gl(), "labs(x='', y='Balances ($B)')")
})
}
shinyApp(ui, server)
Upvotes: 0
Views: 470
Reputation: 1095
The error is occurring because of
paste0("ggplot(data=TP, aes(Date)) + ", gl, "labs(x='', y='Balances ($B)')")
You need to refer to gl
as gl()
since it is a reactive object. After fixing this, there is another error in
DF <- reactive({
df <- df[,c('Date', names(df)[grep(paste(input$states, collapse='|'), names(df))])]
return(tpreg)
})
As there is no tpreg
object in that function. Changed it to return(df)
.
Then nothing displays in the plot. I wanted to help fix the rest but I've never seen anyone paste()
together a plot so I'm not sure that works...
UPDATE:
Ok.
library(shiny)
library(ggplot2)
library(scales)
library(lubridate)
library(tidyr)
df <- data.frame(Date=seq.Date(as.Date('2017-01-01'), as.Date('2017-05-01'), by='month'),
CAact=rnorm(5, 10, 2), TXact=rnorm(5, 10, 2), NYact=rnorm(5, 10, 2),Totalact=rnorm(5, 30, 2),
CAfct=rnorm(5, 10, 2), TXfct=rnorm(5, 10, 2), NYfct=rnorm(5, 10, 2), Totalfct=rnorm(5, 30, 2),
CApred=rnorm(5, 10, 2), TXpred=rnorm(5, 10, 2), NYpred=rnorm(5, 10, 2), Totalpred=rnorm(5, 30, 2)
)
df <- gather(df, Variable, Value, -Date)
df$State <- gsub('act|fct|pred', '', df$Variable)
df$Variable <- gsub('CA|NY|TX|Total', '', df$Variable)
df$State <- factor(df$State, levels = c('CA','NY','TX','Total'))
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput('states', 'Select Regions',
choices=c('CA','TX','NY','Total'),
selected=c('CA','TX','NY','Total')
)
),
mainPanel(
plotOutput('portfolio')
)
)
)
server <- function(input, output){
#Function to subset df based on user selected states
color.groups <- c(CA = 'green', TX = 'blue', NY = 'red', Total = 'black')
line.types <- c(pred = 1, act = 4, fct = 5)
#Generate all the 'geom_line' statements to create ggplot
#Create ggplot (not working)
output$portfolio <- renderPlot({
sub <- subset(df, subset = State %in% input$states)
ggplot(sub, aes(x = Date, y = Value, col = State))+
geom_line(aes(linetype = Variable))+
scale_color_manual(values = color.groups)+
scale_linetype_manual(values = line.types)
})
}
shinyApp(ui, server)
Upvotes: 1