Unable to use reactive element in my shiny app - r

In my shiny app,I want to change the ggplot barChart that I wish to construct. selectinput should allow to change the month (see dataset below) and so my plot should change accordingly.
problem: The isssue is, i am unable to use my reactive function or even just simple input$monthid within ggplot function.
Dataset:
Month Orders
1 Feb 984524
2 Jan 1151303
3 Mar 575000
> dput(b)
structure(list(Month = c("Feb", "Jan", "Mar"), Orders = c(984524L,
1151303L, 575000L)), .Names = c("Month", "Orders"), class = "data.frame", row.names = c(NA,
-3L))
ui.R
library(shiny)
library(shinythemes)
b<-read.csv("b.csv",header=TRUE,sep=",",stringsAsFactors=TRUE)
shinyUI(fluidPage(theme= shinytheme("flatly"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "monthid", label = "Month",choices = b$Month,selected = b$Month[1])),
mainPanel(plotOutput("plot"))
))
)
server.R
library(shiny)
library(shinythemes)
library(ggplot2)
b<-read.csv("b.csv",header=TRUE,sep=",",stringsAsFactors=TRUE)
shinyServer(function(input, output) {
#making a reactive object
m<-reactive ({
as.character(input$monthid)
})
output$plot<- renderPlot({
#probably I am making a subset error in x inside aes parameter
ggplot(data = b, aes(x = b[,m()] ,y = b$Orders)) + geom_bar(stat="identity")
})
})

Here's a minimal working example you can copy and paste right in your session to run, but a bar chart with a single bar doesn't really make a lot of sense (and looks ugly if you ask me):
library(shiny)
shinyApp(
ui = fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "monthid",
label = "Month",
choices = b$Month,
selected = b$Month[1]
)
),
mainPanel(plotOutput("plot"))
)
),
server = function(input, output) {
DF <- reactive({
b[b$Month == input$monthid, , drop = FALSE]
})
output$plot <- renderPlot({
ggplot(DF(), aes(x = Month, y = Orders)) +
geom_bar(stat = "identity")
})
}
)
It looks somewhat like this:
Since that doesn't look nice IMO, you could do something with highlighting the currently selected bar, for example:
b$highlight <- factor("Not Selected", levels = c("Not selected", "Selected"))
shinyApp(
ui = fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "monthid",
label = "Month",
choices = b$Month,
selected = b$Month[1]
)
),
mainPanel(plotOutput("plot"))
)
),
server = function(input, output) {
DF <- reactive({
b[b$Month == input$monthid, "highlight"] <- "Selected"
b
})
output$plot <- renderPlot({
ggplot(DF(), aes(x = Month, y = Orders, fill = highlight)) +
geom_bar(stat = "identity")
})
}
)
This would look as follows:

Related

undefined column selected error in Shiny app

I just want to imitate to make a little shiny app.
but it does not work at all.
ERORR is: Warning: Error in [.data.frame: undefined columns selected
I load a df I created.
data.frame : df_pris_salary
colnames : region , år , Antal ,Medelpris, Medianpris ,MedelLön year_per_lgh
Code looks like this:
library(shiny)
library(tidyverse)
library(ggplot2)
load("data/shiny2.RData")
# load df: df_pris_salary
ui <- fluidPage(
titlePanel("Utveckling av lägenhetspris & Lön"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "VarX",
label = "Select X-axis Variable:",
choices = list("år", "MedelLön")),
selectInput(inputId = "VarY",
label = "Select Y-axis Variable:",
choices = list("Medelpris", "MedelLön")),
selectInput(inputId = "Color",
label = "Select Color Variable:",
choices = as.list(c("region", "år")))
),
mainPanel(
plotOutput("scatter")
)
)
)
server <- function(input, output, session) {
output$scatter <- renderPlot({
mtc <- df_pris_salary[,c(input$VarX, input$VarY, input$Color)]
mtc[,3] <- as.factor(mtc[,3])
ggplot()+
geom_line(data = mtc, aes(x = mtc[,1], y = mtc[,2], color = mtc[,3]))+
geom_point(data = mtc, aes(x = mtc[,1], y = mtc[,2], color = mtc[,3]))+
labs(x = colnames(mtc)[1], y = colnames(mtc)[2],
color = colnames(mtc)[3],
title = paste("Scatter Plot of", input$VarX, "vs", input$VarY),
subtitle = "Under åren 2000 - 2021",
caption = "Data Source: SCB")
})
}
shinyApp(ui, server)
Could someone help me to figure out how to solve this problem?

Make a second SelectInput dropdown reactive

I have two SelectInput Drowpdown controls but I can't make the first one reactive. My second control works fine. Consider this small toy example: On my first dropdown (which it doesn't work), I have 5 options. I want this control to react when the selection changes. I basically want both of my dropdown controls to be reactive to the type of model or type of graphic selected.
library(shiny)
library(ggplot2)
library(tidyverse)
library(shinythemes)
library(plotly)
library(scales)
library(shinyWidgets)
library(shinydashboard)
library(DT)
library(shinyjs)
library(shinycssloaders)
# Define input choices
type <- c("lambda","indices")
model <- c("Output_21yr_noStock","Output_21yr_yesStock","Output_82yr_bdc_noStock","Output_82yr_ppp_noStock","Output_82yr_woa_nostock")
#############Lambda######Table
olddir <- getwd()
table <- structure(list(year = 1991:2010, lambda = c(0.73392, 0.75659,
1.33665, 1.06641, 1.27145, 1.01077, 0.66983, 1.6427, 0.96414,
0.55648, 0.50556, 1.08024, 0.8706, 0.89665, 1.00807, 1.01967,
0.73131, 1.1161, 1.10219, 1.35085)), row.names = c(NA, -20L), class = "data.frame")
table
# Define UI
ui <- fluidPage(
useShinyjs(), # to initialise shiny
theme = shinytheme("superhero"),
navbarPage("Species: Pink Salmon",
windowTitle = "Salmon Model Application",
sidebarPanel(width = 3,
h3("Select Model Output"),
selectInput(inputId = "model",
label = "Model to Run",
choices = model,
selected = "Output_21yr_noStock"),
selectInput(inputId = "graphtype",
label = "Graphic",
choices = type,
selected = "lambda"),
#Slider to select custom years
chooseSliderSkin("Square"),
setSliderColor(c("LightSeaGreen ", "#FF4500", "", "Teal"), c(1, 2, 4)),
#tags$style(type = "text/css", ".irs-grid-pol.small {height: 0px;}"), #hide small ticks
sliderInput(inputId = "Yearslider",
label = "Years to plot",
sep = "",
min = min(table$year), #min and max values of spawner_maturity table6
max = max(table$year),
step = 1,
value = c(min = min(table$year),max = max(table$year))
)),
#Graphic Area mainPanel. Graphic on top and table right below it
mainPanel(
plotOutput("plot")
)))
server<- function (input, output, session) {
session$onSessionEnded(function() {
stopApp()
})
plot_data <- reactive({
table[table$year >= input$Yearslider[1] & table$year <= input$Yearslider[2], ]
})
dataInput <- reactive({
switch(input$graphtype,
"lambda" = plot_data())
})
#How can I make the "model" SelectInput drowpdown control reactive when I select a different model? The "modelInput" below is not reacting.
modelInput <- reactive({
switch(input$model,
"Output_21yr_noStock" = input$model,
"Output_21yr_yesStock" = input$model)
})
# Plot data
create_plots <- reactive({
theme_set(theme_classic(14))
xlabels <- c(min(table$year):max(table$year))
if (input$graphtype == "lambda") {
ggplot(plot_data(),aes(year,lambda)) + geom_line(size=1.5,colour="blue") +
geom_point(colour="orange",size=4) + geom_hline(yintercept=1,color="hotpink",linetype="dashed") +
scale_x_continuous("",breaks = xlabels) + legendTheme +
theme(axis.text.x = element_text(angle = 45, vjust = 0.5)) +
labs(x="",y=expression("Lambda ("~lambda *")"),
title= paste0("Modeled Population growth rate of Delta Smelt cohort years ",
table[table$year >= input$Yearslider[1] & table$year <= input$Yearslider[2], ]))
}
})
#Render plots
output$plot <- renderPlot({
create_plots()
},height = 475)
}
# Run the application
shinyApp(ui = ui, server = server)

Scatterplot in Shiny

I am trying to create a scatterplot based on a csv I have loaded however when I run the code I either get no plot showing or an error when I include the aes mapping: "Mapping should be created with aes() or aes_()."
Can anyone give me pointers on where I am going wrong?
Code:
library(shiny)
library(ggplot2)
ui <- (fluidPage(
titlePanel("Pig Breeds"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "x",
label = "Pig Breeds:",
choices = c("total_pigs", "female_breeding_herd",
"in_pig_sows", "in_pig_gifts", "other_sows",
"maiden_gilts", "boars_for_service", "other_pigs"),
selected = "total_pigs"),
selectInput(inputId = "y",
label = "Year by year change:",
choices = c(2016, 2017, 2018, "year_on_year_change"),
selected = 2016),
actionButton(inputId = "update", label = "update")
),
mainPanel = (
plotOutput(outputId = "scatterplot")
)
)
)
)
server <- (function(input, output) {
output$scatterplot <- renderPlot({
ggplot(data=(read.csv("eu_pigs.csv")),
aes(x = output$x, y = output$y) +
geom_point())
observeEvent(input$update, {print(as.numeric(input$update))})
}
)
}
)
shinyApp(ui, server)
As the error message says, you’re using aes incorrectly. The function takes column names, not variable references. That is, replace
aes(x = output$x, y = output$y)
by
aes(x = x, y = y)
Or, more likely you want to be able to control the plot from the inputs, so you’d want to use
aes_string(x = input$x, y = input$y)
There are also quite a few stray parentheses and braces in your code. Remove those. Furthermore, mainPanel is a function that you need to call. Your code is instead assigning something to it.
And lastly, you actually need to plot your plot. After all these things are fixed, the relevant code looks like this:
ui <- fluidPage(
titlePanel("Pig Breeds"),
sidebarLayout(
sidebarPanel(…),
mainPanel(
plotOutput(outputId = "scatterplot")
)
)
)
server <- function(input, output) {
output$scatterplot <- renderPlot({
p = ggplot(data = read.csv("eu_pigs.csv")) +
aes_string(x = input$x, y = input$y) +
geom_point()
plot(p)
observeEvent(input$update, print(as.numeric(input$update)))
})
}
If the plot object is the last thing you are executing in the renderPlot function, you can omit plot:
output$scatterplot <- renderPlot({
ggplot(data = read.csv("eu_pigs.csv")) +
aes_string(x = input$x, y = input$y) +
geom_point()
})

Dynamic filters and reactive plot in Shiny

Issues between inputs and plot output
Hi,
I'm testing out a basic ShinyApp where I can generate a plot of commercial services broken down by geography and service type.
The idea is I want the user to use three drop-down menu inputs, each dependent upon the previous selection, to subset the data, which then gets output in a ggplot.
However, I'm having issues connecting the inputs to the plot output (see below). The inputs are working fine and reactive when selected, but I can't work out how to link that to the plot, I get the feeling I'm not using the right data source (but have no idea how to ensure it is). Furthermore, I'm not familiar with how I would go about adding a third filter (for "service") seeing as I don't know how to link my data source in the first place.
Sorry this is probably simple, but some help would be really appreciated.
UI
#Data
Test <- dataframe(
Geography1 = c("Region","Local Authority","County"...),
Geography2 = c("North West","Aldershot","Cheshire"...),
Service = c("Shop","Cafe","Library"...),
Overall_rating = c("Awesome","Good","Fantatstic"...),
Locations = c(4000, 1300, 1700...)
)
#SHINY APP
ui <- fluidPage(
titlePanel("Tool"),
sidebarLayout(
sidebarPanel(
uiOutput("geography1"),
uiOutput("geography2"),
uiOutput("service")),
mainPanel(
plotOutput("plot", height = "400px"))
)
)
Server
server <- function(input, output) {
output$geography1 = renderUI({
selectInput(inputId = "geog1",
label = "Geography 1:",
choices = as.character(unique(Test$Geography1)),
selected = "Region")
})
output$geography2 = renderUI({
datasub <- Test[Test$Geography1 == input$geog1, "Name"]
selectInput(inputId = "geog2",
label = "Geography2:",
choices = unique(datasub),
selected = unique(datasub)[1])
})
output$service = renderUI({
datasub2 <- unique(datasub)
selectInput(inputId = "service",
label = "Service type:",
choices = unique(...),
selected = unique(...)[1])
})
output$plot = renderPlot({
ggplot(datasub2(),aes(x = Overall_rating, y = Locations, fill= Overall_rating))+
geom_bar(stat = "identity")
})
}
shinyApp(ui, server)
It's hard to tell how the provided data is supposed to be filtered in the app but this code will at least run and be interactive. Hopefully from there you can figure out how to adjust the dataset.
As BigDataScientist said one fault is that you're not using a reactive dataset.
#Data
Test <- data.frame(
Geography1 = c("Region","Local Authority","County"),
Geography2 = c("North West","Aldershot","Cheshire"),
Service = c("Shop","Cafe","Library"),
Overall_rating = c("Awesome","Good","Fantatstic"),
Locations = c(4000, 1300, 1700)
)
#SHINY APP
ui <- fluidPage(
titlePanel("Tool"),
sidebarLayout(
sidebarPanel(
uiOutput("geography1"),
uiOutput("geography2"),
uiOutput("service")),
mainPanel(
plotOutput("plot", height = "400px"))
)
)
server <- function(input, output) {
output$geography1 = renderUI({
selectInput(inputId = "geog1",
label = "Geography 1:",
choices = as.character(unique(Test$Geography1)),
selected = "Region")
})
datasub <- reactive({
Test[Test$Geography1 == input$geog1,]
})
output$geography2 = renderUI({
selectInput(inputId = "geog2",
label = "Geography2:",
choices = unique(datasub()[,"Geography2"]),
selected = unique(datasub()[,"Geography2"])[1])
})
datasub2 <- reactive({
datasub()[Test$Geography2 == input$geog2, ]
})
output$service = renderUI({
selectInput(inputId = "service",
label = "Service type:",
choices = unique(datasub2()[,"Service"]),
selected = unique(datasub2()[,"Service"])[1])
})
datasub3 <- reactive({
datasub()[Test$Service == input$service, ]
})
output$plot = renderPlot({
ggplot(datasub3(),aes(x = Overall_rating, y = Locations, fill= Overall_rating))+
geom_bar(stat = "identity")
})
}
shinyApp(ui, server)

Interactive renderplot graph with multidimensional dataset

I am trying to run an interactive rshiny plot. I have this output:
I want to be able to subset and plot by country, by scenario, by variable, by year (4 selections). I also want to be able to add value points by year and not have the whole plot by year done immediately.
I am only able to subset by country. My scenario and variable dropdowns are not reactive. And it plots all variables with all scenarios although I want one variable plot by one scenario and one country
How can I make my graph interactive?
library(reshape2)
library(lattice)
library(plyr)
library(shiny)
library(dplyr)
library(abind)
library(ggplot2)
ui <- fluidPage(
titlePanel("Comparing Trend and PP policies by MDGs and funding"),
sidebarLayout(
sidebarPanel(
radioButtons("radio", label = h3("Country"),choices=unique(dmiubf$country), selected = ""),
selectInput("Senario","Show senario:", choices = unique(dmiubf$scn)),
selectInput("var","Show senario:", choices = unique(dmiubf$var)),
selectInput("year","Show vertical line in year(s):", choices = unique(dmiubf$year),multiple=TRUE)
),
mainPanel(
plotOutput("chart")
)
)
)
server <- function(input, output) {
cr <- reactive({
a = dmiubf[dmiubf$var==input$var, dmiubf$scn==input$senario]<-dmiubf[dmiubf[,"country"]=="Costa Rica",input$senario]<-"base"
dmiubf
})
output$chart <- renderPlot({
req(input$radio)
if (input$radio==c("Costa Rica")) {
plot0<-ggplot(data=cr()) + geom_point(aes(x=year,y=pcn, fill=scn),
size = 6)
print(plot0)
}
})
}
shinyApp(ui = ui, server = server)
I tried fixing your app, but without knowing how the input data looks like, its a bit hard. So i created a random dummy dataset. Therefore it is not always showing a plot, as no data is left after the filtering process.
But as a starting point I think this should help you:
library(shiny)
library(dplyr)
library(ggplot2)
dmiubf <- data.frame(
country=c(rep("Costa Rica",8), rep("England",8), rep("Austria",8), rep("Latvia",8)),
scn = rep(c("base","high","low","extra"),8),
year = sample(c(1998, 1999, 2000, 2001), 32, replace = T),
var = sample(c(1,2,3,4), 32, replace = T),
pcn = sample(c(10,20,30,40), 32, replace = T)
)
ui <- fluidPage(
titlePanel("Comparing Trend and PP policies by MDGs and funding"),
sidebarLayout(
sidebarPanel(
radioButtons("radio", label = h3("Country"),choices= as.character(unique(dmiubf$country)), selected = ""),
selectInput("Senario","Show senario:", choices = as.character(unique(dmiubf$scn))),
selectInput("var","Show senario:", choices = sort(unique(dmiubf$var))),
selectInput("year","Show vertical line in year(s):", choices = sort(unique(dmiubf$year)), multiple=TRUE)
),
mainPanel(
plotOutput("chart")
)
)
)
server <- function(input, output) {
cr <- reactive({
a <- dmiubf[as.character(dmiubf$country)==input$radio &
dmiubf$var %in% as.numeric(input$var) &
dmiubf$year %in% as.numeric(input$year) &
as.character(dmiubf$scn)==input$Senario
,]
a
})
output$chart <- renderPlot({
validate(
need(nrow(cr())!=0, "No Data to plot")
)
ggplot(data=cr()) + geom_point(aes(x=year, y=pcn, fill=scn), size = 6)
})
}
shinyApp(ui = ui, server = server)

Resources