1

I know this has been answered numerous times and I also found a detailed explanation about position_dodge to align the bar graph labels in this post What is the width argument in position_dodge?

But for some reason, I am not able to figure out the dodge position for my situation. I am creating a reactive dataset to get a count by a metric which is selected from a drop down menu and this is then passed to ggplot2, below is my code. input$qtr and input$met are selected by user.

library(readxl)
library(shiny)
library(ggplot2)
library(dplyr)
library(zoo)
library(shinydashboard)

data ("mtcars")
df$Qtr <- ifelse(mtcars$am==1, "2018Q1","2018Q2")
df$Responsibility <- ifelse(mtcars$gear %in% c(3, 4), "Category 1","Category 
2")
df$Leader <- ifelse(mtcars$vs==0, "No","Yes")
df$Failure <- ifelse(mtcars$carb %in% c(1, 2), "Quality","Timing")
df$Cname <- ifelse(mtcars$carb %in% c(1, 2), "Company 1","Company 2")
df <- df[,c("Cname", "Responsibility", "Qtr", "Leader","Failure")]





ui <- dashboardPage(skin="blue",
                dashboardHeader(title = "R Shiny Concept",titleWidth = 200),
                # Sidebar layout with a input and output definitions
                dashboardSidebar(id="", sidebarMenu(uiOutput("qtr"),
                  menuItem("All", tabName = "all", icon = icon("bars")))),

                dashboardBody (tabItems(tabItem(tabName = "all",
                          fluidRow(uiOutput("met")),
                          fluidRow(plotOutput(outputId = "metrics"))))))

server <- function(input, output, session) {  
# Drop-down selection box for quarter
output$qtr <- renderUI({selectInput(inputId = "qtr", 
            label = "Pick a Quarter", 
            choices= as.list(gsub(" ","",df$Qtr)),
            selected = 1)})

# Drop-down selection box for metrics
output$met <- renderUI({selectInput(inputId = "met", 
            label = "Pick a metrics to report", 
            choices= c("Responsibility", 
                       "Leader", 
                       "Failure"),
            selected = 1)})

#  Create a subset of data filtering for selected CRO
freq_subset2 <- reactive({
req(input$qtr)
req(input$met)

df %>%
group_by_at(vars(Cname, Qtr,(input$met))) %>%
select(Cname, Qtr,(input$met)) %>%
summarise(count = n()) %>% 
filter(gsub(" ","",Qtr) %in% input$qtr)
})

plot3 <- output$metrics <- renderPlot({
ggplot(data = freq_subset2(), aes(x=Cname, y=count)) +
labs(y=" ", x = " ")+
geom_bar(stat="identity", position = "dodge", width=0.8, aes_string(fill =
(input$met))) +   
geom_text(aes(label=count), color="black",position = 
position_dodge(width=0.8),
         hjust = 1.5, size=3.5) +scale_fill_brewer(palette="Set1") +
theme(axis.ticks = element_blank(),axis.text.y = element_blank(),
     panel.grid.minor = element_blank(), 
    panel.grid.major = element_blank(),panel.background= element_blank(), 
   plot.title = element_text(size = rel(1.5), face = "bold"),
  legend.position="bottom",legend.title = element_text(color = "white"))

})
plot3

}
# Create the Shiny app object
shinyApp(ui = ui, server = server)

Here is the output enter image description here

Cyrus N
  • 13
  • 4
  • I think the trick is to keep the width same in both then use `hjust` to get what you want, `geom_bar(aes(y = value,fill = variable),stat = "identity",position = "dodge",width = .8,colour="Black")` and `geom_text(aes(label = sprintf("%.0f%%",value)),angle = 00 , hjust = 0.5, vjust = -.5, col = "black", cex = 3, position = position_dodge(.8)) ` – A. Suliman Apr 24 '18 at 03:36
  • Thanks A. Suliman, but this is not working for me too. Is this because my fill = parameter is coming from a drop down? I have exhaustively tried all options but none seems to work. I have another plot with fill=variable and its working as expected. – Cyrus N Apr 24 '18 at 14:42
  • If you can provide a small reproducible example, may be I can help. – A. Suliman Apr 24 '18 at 15:07
  • HI Suliman - I updated my original post to add simplified program of the app I am trying to create. User will first select the quarter in the sidemenubar and then select a metrics from the drop down in the body. – Cyrus N Apr 25 '18 at 01:19

1 Answers1

0
server <- function(input, output, session) {  
         # Drop-down selection box for quarter
         output$qtr <- renderUI({selectInput(inputId = "qtr", 
                                  label = "Pick a Quarter", 
                                  choices= as.list(gsub(" ","",df$Qtr)),
                                  selected = 1)})

         # Drop-down selection box for metrics
          output$met <- renderUI({selectInput(inputId = "met", 
                                  label = "Pick a metrics to report", 
                                  choices= c("Responsibility", 
                                             "Leader", 
                                             "Failure"),
                                  selected = 1)})

      #  Create a subset of data filtering for selected CRO
        freq_subset2 <- reactive({
           req(input$qtr)
           req(input$met)

           df %>%
              group_by_at(vars(Cname, Qtr,(input$met))) %>%
              select(Cname, Qtr,(input$met)) %>%
              summarise(count = n()) %>% 
              filter(gsub(" ","",Qtr) %in% input$qtr)


  })

           #observe(print(freq_subset2()))
           plot3 <- output$metrics <- renderPlot({
                    ggplot(data = freq_subset2(), aes_string(x="Cname", y="count", fill= as.character(input$met))) +
  labs(y=" ", x = " ") + geom_bar(stat="identity", position = "dodge", width=0.8) +
  #geom_bar(stat="identity", position = "dodge", width=0.8, aes_string(fill = (input$met))) +   
  geom_text(aes(label=count), color="black",position = 
              position_dodge(width=0.8),
            hjust = 0.5,vjust=-1, size=3.5) +scale_fill_brewer(palette="Set1") +
  theme(axis.ticks = element_blank(),axis.text.y = element_blank(),
        panel.grid.minor = element_blank(), 
        panel.grid.major = element_blank(),panel.background= element_blank(), 
        plot.title = element_text(size = rel(1.5), face = "bold"),
        legend.position="bottom",legend.title = element_text(color = "white"))

      })
      plot3

  }
   # Create the Shiny app object
   shinyApp(ui = ui, server = server)

You are correct the problem was how to pass input$met as unquoted variable to fill. Here is the link which save my day Loooool. I hope it helps ;)

A. Suliman
  • 12,923
  • 5
  • 24
  • 37
  • Thank you so much A. Suliman! this works great. I was behind this for couple of days and you saved my sleepless nights :) .. Thank you again!! – Cyrus N Apr 25 '18 at 12:07