Julie Mugford
Julie Mugford

Reputation: 77

stacked geom_bar in shiny that depends on select input

I'm trying to include a stacked bar chart in shiny that depends on a select input. It works fine outside of shiny but in shiny it is not displaying multiple bars.

Code:

library(shiny)
library(ggplot2)
# Define UI  ----
ui <- fluidPage(

  # Application title
  titlePanel("Group fairness analysis"),

  # Sidebar 
  sidebarLayout(
    sidebarPanel(
      selectInput("group", "Group:", 
                  c("Age" = "age",
                    "Gender" = "gender",
                    "Region" = "region",
                    "Ethnicity"="ethnicity"))
      ),

    # Show a plot of the generated distribution
    mainPanel(
      h3("Accuracy bar chart"),
      plotOutput("accPlot")
    )
  )
)

# Define server logic ----
server <- function(input, output) {
  output$accPlot <- renderPlot({   
    g2 <- ggplot(df %>% count(get(input$group),correct) , aes(x=c(input$group),y=n,fill=as.factor(correct))) +
      geom_bar(stat="identity",position=position_fill())+
      scale_y_continuous(labels = scales::percent) +
      geom_text(aes(label = paste0((n/nrow(df))*100,"%")), position = position_fill(vjust = 0.5), size = 5)+
      theme_bw()+
      ylab("")+
      coord_flip()
    g2

  })

}

shinyApp(ui, server)

Sample data

# data -----------------------------------------------------------
n<-20 #number of users
threshold <- 60 #threshold in risk score for referral to YS
df <- data.frame(age = rep(0,n),
                 gender = rep(0,n),
                 ethnicity = rep(0,n),
                 region = rep(0,n),
                 score = rep(0,n),
                 referred = rep(0,n),
                 target = rep(0,n))

df$age <- as.factor(sample(c(15,16,17),size=n,replace=TRUE))
df$gender <- as.factor(sample(c('M','F'),size=n,replace=TRUE))
df$ethnicity<- as.factor(sample(c('European','Maori','Pacific','other'),size=n,replace=TRUE))
df$region<-as.factor(sample(c('North','Mid','South'),size=n,replace=TRUE))
df$score<-runif(n,min=0,max=100)
df$target<-sample(c(0,1),size=n,replace = TRUE)

df[which(df$score>=threshold),"referred"]<-1

df$colour<-rep(0,n)
df[which(df$referred==1 & df$target==1),"colour"]<-1
df[which(df$referred==1 & df$target==0),"colour"]<-2
df[which(df$referred==0 & df$target==1),"colour"]<-3
df[which(df$referred==0 & df$target==0),"colour"]<-4

df$correct<-rep(0,n)
df[which(df$referred==0 & df$target==0),"correct"]<-1
df[which(df$referred==1 & df$target==1),"correct"]<-1
df[which(df$referred==0 & df$target==1),"correct"]<-0
df[which(df$referred==1 & df$target==0),"correct"]<-0

enter image description here

It should look like

enter image description here

Upvotes: 0

Views: 489

Answers (1)

Ben
Ben

Reputation: 30494

Your input$group from selectInput is a string, not a variable symbol. You can convert it to a symbol for your ggplot with rlang::sym and evaluate with !!.

In addition, your aesthetic for ggplot can use aes_string and refer to your column names as strings.

And would convert your correct column to a factor separately.

df$correct <- as.factor(df$correct)

...

g2 <- ggplot(df %>% count(!!rlang::sym(input$group), correct), aes_string(x=c(input$group), y="n", fill="correct")) + 

...

Upvotes: 1

Related Questions