I have the following dataset:
data <- structure(list(country = c("Andorra", "Austria", "Belgium", "Denmark", "Finland", "France", "Germany", "Greece"), x48 = c(811.73, 710.0385, 765.8359, 961.434, 701.9176, 716.7308, 701.6187, 468.1942), x49 = c(655.2433, 607.8058, 628.3675, 692.426, 575.4287, 587.7711, 544.2052, 370.2103), x54 = c(2801.597, 2224.757, 2320.216, 3130.023, 2582.625, 2399.011, 2621.368, 804.5603)), class = "data.frame", row.names = c(NA, -8L))
I want to plot a double bar chart that shows, for each country in the x-axis, a bar with the values of 'x54' and a bar for either 'x48' or 'x49' like so:
With the following code:
library(shiny)
library(ggplot2)
library(tidyverse)
df <- read.csv("data/salario-apartamento-europa-occidental-pequeño.csv")
ui = fluidPage(
titlePanel("Triple Bar Chart"),
sidebarLayout(
sidebarPanel(
selectInput("x1", "Type of house:", choices = names(df)[-1], selected = names(df)[1]),
),
mainPanel(
plotOutput("plot")
)
)
)
server = function(input, output) {
output$plot <- renderPlot({
df_long <- df %>% pivot_longer(-country)
ggplot(data = df_long %>%
filter(name %in% c("x49", "x54")),
aes(x = country, y = value, fill = factor(name)))
geom_col(position = position_dodge())
scale_fill_manual(values = c("#58C114", "#DA560A"))
theme_light()
theme(axis.text.x = element_text(angle = 90))
scale_color_manual(name = "Metric", labels = c("1 room in the center", "Average Monthly Salary"))
labs(fill =" Metric", x= "Country", y= "USD")
})
}
# run the app
shinyApp(ui, server)
I can do it as you can see, but you'll realize that, instead of filtering by 'x54' and the input variable "x1", I'm filtering by 'x49' thus, instead of being reactive, for me to compare 'x54' and 'x48', I have to change it manually in the code.
I would like to have something similar to this:
filter(name %in% c(input$x1, "x54"))
But unfortunatelly, this doesn't work and it only plots 'x54'.
Also, how would I update the labels accordingly? (Now they stay like 'x49' and 'x54' as you can see in the picture)
It should be like so:
For 'x54': Average Monthly Salary
For 'x48': 1 room in the center
And for 'x49': 1 room outside the center
Thank you very much in advance for the help!
CodePudding user response:
In the selectInput
, the object used is data
and not df
selectInput("x1", "Type of house:", choices = names(df)[-1],
selected = names(df)[1]),
),
...
where
df <- read.csv("data/salario-apartamento-europa-occidental-pequeño.csv")
-full code
df <- structure(list(country = c("Andorra", "Austria", "Belgium", "Denmark", "Finland", "France", "Germany", "Greece"), x48 = c(811.73, 710.0385, 765.8359, 961.434, 701.9176, 716.7308, 701.6187, 468.1942), x49 = c(655.2433, 607.8058, 628.3675, 692.426, 575.4287, 587.7711, 544.2052, 370.2103), x54 = c(2801.597, 2224.757, 2320.216, 3130.023, 2582.625, 2399.011, 2621.368, 804.5603)), class = "data.frame", row.names = c(NA, -8L))
ui = fluidPage(
titlePanel("Triple Bar Chart"),
sidebarLayout(
sidebarPanel(
selectInput("x1", "Type of house:", choices = names(df)[-1], selected = names(df)[1]),
),
mainPanel(
plotOutput("plot")
)
)
)
server = function(input, output) {
output$plot <- renderPlot({
req(input$x1)
df_long <- df %>% pivot_longer(-country)
ggplot(data = df_long %>%
filter(name %in% c(input$x1, "x54")),
aes(x = country, y = value, fill = factor(name)))
geom_col(position = position_dodge())
scale_fill_manual(values = c("#58C114", "#DA560A"),
labels= setNames( c("1 room in the center", "Average Monthly Salary"), c("x48", "x49")))
theme_light()
theme(axis.text.x = element_text(angle = 90))
labs(fill =" Metric", x= "Country", y= "USD")
})
}
# run the app
shinyApp(ui, server)
-output
CodePudding user response:
Your input
needs to be a reactive. https://mastering-shiny.org/basic-reactivity.html
Your server would need to look more like this.
server = function(input, output) {
yourinput <- reactive({
input$x1
})
output$plot <- renderPlot({
df_long <- df %>% pivot_longer(-country)
ggplot(data = df_long %>%
filter(name %in% c(yourinput(), "x54")),
aes(x = country, y = value, fill = factor(name)))
geom_col(position = position_dodge())
scale_fill_manual(values = c("#58C114", "#DA560A"))
theme_light()
theme(axis.text.x = element_text(angle = 90))
scale_color_manual(name = "Metric", labels = c("1 room in the center", "Average Monthly Salary"))
labs(fill =" Metric", x= "Country", y= "USD")
})
}