1

I am using Shiny to build a simple dashboard to use in my job. Everything was fine until I found that I couldn't pass chosen input to be used as an argument in ggplot geom_col() interaction arguments.

My purpose is to change interaction plot based on chosen values of checkboxGroup where the chosen values will be used as arguments for fill=interaction(....) in ggplot.

I faced problem at this stage :

ggplot(data= opsdata2, aes(x=reorder(GUDANG,KUANTUM/1000), y=KUANTUM/1000, 
                                   fill=interaction(get(input$cekgr_fill),sep = "*")
               ))

The 'get(input$cekgr_fill)' only pass the first argument only whereas my purposes is to build interaction barplot using at least 2 arguments in input$cekgr_fill, ex: 'fill=interaction(JENIS,TH_ADA, sep="*")'.

The 'get(input$cekgr_fill)' only pass the first argument, i.e : JENIS, and ignore TH_ADA.

Would you please help me? Thank you.

Here is my code :

    shinyUI(dashboardPage(

    #Nama Dashboard
     dashboardHeader(title = "OPERASIONAL"),
              
              dashboardSidebar(
                
                checkboxGroupInput("cekgr_gudang", label = h4("Gudang"),
                                   choiceNames = list("Karanganyar","Binong",
                                           "Rancaudik","Tanjungrasa",
                                           "Ciwangi"),
                                   choiceValues = list("Karanganyar","Binong",
                                                       "Rancaudik","Tanjungrasa",
                                                       "Ciwangi")
                                   ),
                 
                checkboxGroupInput("cekgr_komoditas", label = h4("Komoditas"),
                                   choices = c("Beras","Minyak Goreng", 
                                               "Terigu","Gula","Gabah", "Ketan")
                                   ),
                
                checkboxGroupInput("cekgr_tahun","Tahun",
                                  choices = c("2018","2019","2020","2021")
                                  ),
                
                checkboxGroupInput("cekgr_opsional", label = h4("Opsional"),
                                   choices = c("Fumigasi", "Kondisi kualitas")
                                   
                                   ),
               
                checkboxGroupInput("cekgr_fill", label = h4("Fill Grafik"),
                                   choiceNames = c("JENIS","TAHUN"),
                                   choiceValues = c("JENIS", "TH_ADA")
                                   ),
                 
                actionButton("OK","Sikaaat")
                
              ),

    ## BODY

    dashboardBody(
       fluidRow(
       column(
       width = 12,

        box(title = "Grafik Yang Kamu Minta ",
        solidHeader = T,
        width = 8, height = 500,
        collapsible = T,
        plotOutput("grafik1"),
        textOutput("PilihanGudang"),
        textOutput("PilihanKomoditas"),
        textOutput("PilihanTahun"),
        textOutput("FillGrafik"))
  
  
           )
        ))))
              




library(shiny)

# Define server logic required to draw a histogram
shinyServer(function(input, output) {
  
  
    #### Pilihan-pilihan
 
observeEvent(input$OK,{
  
  opsdata1 <- read_xlsx("~/Documents/App-Dashboard-Ops/data_Feb_11.xlsx")
  View(opsdata1)
  
  output$PilihanGudang <- renderText({
    gudangterpilih <- paste(input$cekgr_gudang,collapse = ", ")
    paste("Gudang : ", gudangterpilih)})
  
  
  output$PilihanKomoditas <- renderText({
    komoditasterpilih <- paste(input$cekgr_komoditas, collapse = ", ") 
    paste("Komoditas : ", komoditasterpilih)})
  
  output$PilihanTahun <- renderText({
    tahunterpilih <- paste(input$cekgr_tahun, collapse = ", ") 
    paste("Tahun : ", tahunterpilih)})
  
  output$FillGrafik <- renderText({
    fillterpilih <- paste(input$cekgr_fill, collapse = ", ") 
    paste("Fill : ", fillterpilih)})
   
  
  
  
  opsdata2 <- opsdata1 %>%
    
  
    filter(GUDANG %in% input$cekgr_gudang) %>% 
    filter(JENIS %in% input$cekgr_komoditas) %>% 
    filter(TH_ADA %in% input$cekgr_tahun)
  
  View(opsdata2)
      
  output$grafik1 <- renderPlot({
    
    ggplot(data= opsdata2, aes(x=reorder(GUDANG,KUANTUM/1000), y=KUANTUM/1000, 
                               fill=interaction(get(input$cekgr_fill),sep = "*")
           )) + 
      geom_col() + coord_flip() +
      scale_y_continuous(labels = unit_format(unit = "Ton")) +
      labs(x="",y="",fill="") + 
      theme_clean() + theme(legend.position = "top") 
    
  
  })
  
    
  })
  
  
})



here is my data :

structure(list(GUDANG = c("Karanganyar", "Karanganyar", "Karanganyar",    "Karanganyar", "Rancaudik", "Rancaudik", "Rancaudik", "Tanjungrasa", "Tanjungrasa", "Tanjungrasa", "Tanjungrasa", "Binong", "Binong", "Binong", "Binong", "Binong", "Binong", "Binong", "Ciwangi", "Ciwangi", "Ciwangi"), UNIT = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), TUMPUKAN = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), JENIS = c("Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Ketan", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Ketan", "Beras", "Beras", "Beras"), PSO_KOM_HGL = c("PSO", "PSO", "KOM", "KOM", "PSO", "PSO", "PSO", "PSO", "PSO", "KOM", "KOM", "PSO", "PSO", "PSO", "HGL", "KOM", "PSO", "KOM", "PSO", "PSO", "PSO" ), TH_ADA = c(2020, 2019, 2020, 2020, 2020, 2019, 2018, 2020, 2019, 2020, 2020, 2020, 2019, 2020, 2020, 2018, 2018, 2020, 2019, 2018, 2018), KUALITAS = c("Med_20%", "Med_20%", "Kom_10%", "Kom_10%", "Med_20%", "Med_20%", "Med_5%", "Med_20%", "Med_20%", "Kom_10%", "Kom_15%", "Med_20%", "Med_20%", "Kom_15%", "Kom_15%", "Kom_15%", "Med_5%", "Kom_15%", "Med_20%", "Med_5%", "Med_15%"), KEMASAN = c(50, 50, 10, 25, 50, 50, 50, 50, 50, 10, 25, 50, 50, 10, 50, 5, 50, 25, 50, 50, 50), MEREK = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "WJ", NA, NA, NA, NA, "IBU", NA, "WJ", NA, NA, NA), NEGARA = c("Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Thailand", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Thailand", "Indonesia", "Indonesia", "Vietnam", "Vietnam"), EXP = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), KONDISI = c("Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik"), KUANTUM = c(10000, 107500, 12810, 4150, 65000, 4391000, 222850, 320000, 3193550, 2580, 37500, 30000, 2513060, 184720, 2040, 182200, 177270, 20000, 529400, 103500, 449755)), row.names = c(NA, -21L), class = c("tbl_df", "tbl", "data.frame"))

 
                  
deny1110
  • 13
  • 3

1 Answers1

0

You need to select the appropriate variables for interaction. I have used pickerInput to select a maximum of 5 variables for interaction. If less than 2 variables are selected, a message is printed. Perhaps there is a more elegant way of doing this. For now, I have provided a quick answer. Please try this

df1 <- structure(list(GUDANG = c("Karanganyar", "Karanganyar", "Karanganyar", "Karanganyar", "Rancaudik", "Rancaudik", 
                                 "Rancaudik", "Tanjungrasa", "Tanjungrasa", "Tanjungrasa", "Tanjungrasa", "Binong", 
                                 "Binong", "Binong", "Binong", "Binong", "Binong", "Binong", "Ciwangi", "Ciwangi", "Ciwangi"),
                      UNIT = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
                      TUMPUKAN = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
                      JENIS = c("Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", 
                                "Ketan", "Beras", "Beras", "Beras", "Beras", "Beras", "Beras", "Ketan", "Beras", "Beras", "Beras"),
                      PSO_KOM_HGL = c("PSO", "PSO", "KOM", "KOM", "PSO", "PSO", "PSO", "PSO", "PSO", "KOM", "KOM", "PSO", 
                                      "PSO", "PSO", "HGL", "KOM", "PSO", "KOM", "PSO", "PSO", "PSO" ), 
                      TH_ADA = c(2020, 2019, 2020, 2020, 2020, 2019, 2018, 2020, 2019, 2020, 2020, 2020, 2019, 2020, 2020, 2018, 2018, 2020, 2019, 2018, 2018), 
                      KUALITAS = c("Med_20%", "Med_20%", "Kom_10%", "Kom_10%", "Med_20%", "Med_20%", "Med_5%", "Med_20%", "Med_20%", "Kom_10%", "Kom_15%", 
                                   "Med_20%", "Med_20%", "Kom_15%", "Kom_15%", "Kom_15%", "Med_5%", "Kom_15%", "Med_20%", "Med_5%", "Med_15%"),
                      KEMASAN = c(50, 50, 10, 25, 50, 50, 50, 50, 50, 10, 25, 50, 50, 10, 50, 5, 50, 25, 50, 50, 50),
                      MEREK = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "WJ", NA, NA, NA, NA, "IBU", NA, "WJ", NA, NA, NA),
                      NEGARA = c("Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Thailand", 
                                 "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", "Indonesia", 
                                 "Indonesia", "Indonesia", "Thailand", "Indonesia", "Indonesia", "Vietnam", "Vietnam"),
                      EXP = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
                      KONDISI = c("Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", 
                                  "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik", "Baik"), 
                      KUANTUM = c(10000, 107500, 12810, 4150, 65000, 4391000, 222850, 320000, 3193550, 2580, 37500, 30000, 
                                  2513060, 184720, 2040, 182200, 177270, 20000, 529400, 103500, 449755)), 
                 row.names = c(NA, -21L), class = c("tbl_df", "tbl", "data.frame"))

library(shiny)
library(shinydashboard)

ui <- shinyUI(dashboardPage(
  
  #Nama Dashboard
  dashboardHeader(title = "OPERASIONAL"),
  
  dashboardSidebar(
    
    checkboxGroupInput("cekgr_gudang", label = h4("Gudang"),
                       choiceNames = list("Karanganyar","Binong",
                                          "Rancaudik","Tanjungrasa",
                                          "Ciwangi"),
                       choiceValues = list("Karanganyar","Binong",
                                           "Rancaudik","Tanjungrasa",
                                           "Ciwangi")
    ),
    
    checkboxGroupInput("cekgr_komoditas", label = h4("Komoditas"),
                       choices = c("Beras","Minyak Goreng", 
                                   "Terigu","Gula","Gabah", "Ketan")
    ),
    
    checkboxGroupInput("cekgr_tahun","Tahun",
                       choices = c("2018","2019","2020","2021")
    ),
    
    checkboxGroupInput("cekgr_opsional", label = h4("Opsional"),
                       choices = c("Fumigasi", "Kondisi kualitas")
                       
    ),
    
    # checkboxGroupInput("cekgr_fill", label = h4("Fill Grafik"),
    #                    choiceNames = c("JENIS","TAHUN"),
    #                    choiceValues = c("JENIS", "TH_ADA")
    # ),
    
    uiOutput("ivars"),
    
    actionButton("OK","Sikaaat")
    
  ),
  
  ## BODY
  
  dashboardBody(
    fluidRow(
      column(
        width = 12,
        
        box(title = "Grafik Yang Kamu Minta ",
            solidHeader = T,
            width = 8, height = 550,
            collapsible = T,
            plotOutput("grafik1"),
            textOutput("PilihanGudang"),
            textOutput("PilihanKomoditas"),
            textOutput("PilihanTahun"),
            textOutput("FillGrafik"), 
            uiOutput("t1") 
            )
        
      )
    ))))

# Define server logic required to draw a histogram
server <- shinyServer(function(input, output) {
  
  output$ivars<-renderUI({
    bb <- colnames(df1)
    pickerInput(inputId = 'cekgr_fill',
                label = 'Select interaction variables',
                choices = c(bb[1:length(bb)]),  
                multiple = TRUE,
                options = pickerOptions(maxOptions = 5,
                                        header = "Please select at least 2 variables",
                                        `style` = "btn-info")
    )
  })

  #### Pilihan-pilihan
  
  observeEvent(input$OK, {
    
    opsdata1 <- df1 # read_xlsx("~/Documents/App-Dashboard-Ops/data_Feb_11.xlsx")
    
    output$PilihanGudang <- renderText({
      gudangterpilih <- paste(input$cekgr_gudang,collapse = ", ")
      paste("Gudang : ", gudangterpilih)})
    
    
    output$PilihanKomoditas <- renderText({
      komoditasterpilih <- paste(input$cekgr_komoditas, collapse = ", ") 
      paste("Komoditas : ", komoditasterpilih)})
    
    output$PilihanTahun <- renderText({
      tahunterpilih <- paste(input$cekgr_tahun, collapse = ", ") 
      paste("Tahun : ", tahunterpilih)})
    
    output$FillGrafik <- renderText({
      fillterpilih <- paste(input$cekgr_fill, collapse = ", ") 
      paste("Fill : ", fillterpilih)})
    
    output$t1 <- renderUI({
      n <- length(input$cekgr_fill)
      if (n < 2) {
        tagList(
          p("A minimum of two variables are required to show interaction", style = "color:red")
        )
      }else return(NULL)
      
    })
    
    output$grafik1 <- renderPlot({
      opsdata2 <- opsdata1 %>%
        filter(GUDANG %in% input$cekgr_gudang) %>% 
        filter(JENIS %in% input$cekgr_komoditas) %>% 
        filter(TH_ADA %in% input$cekgr_tahun)
      n <- length(input$cekgr_fill)
      
      if (n>1) {
        if (n==2) { 
          opsdata2$ivar <- interaction(opsdata2[[input$cekgr_fill[[1]]]], opsdata2[[input$cekgr_fill[[2]]]], sep = "*")
        }else if (n==3){
          opsdata2$ivar <- interaction(opsdata2[[input$cekgr_fill[[1]]]], opsdata2[[input$cekgr_fill[[2]]]], 
                                       opsdata2[[input$cekgr_fill[[3]]]], sep = "*")
        }else if (n==4) {
          opsdata2$ivar <- interaction(opsdata2[[input$cekgr_fill[[1]]]], opsdata2[[input$cekgr_fill[[2]]]], 
                                       opsdata2[[input$cekgr_fill[[3]]]], opsdata2[[input$cekgr_fill[[4]]]], sep = "*")
        }else if (n==5){
          opsdata2$ivar <- interaction(opsdata2[[input$cekgr_fill[[1]]]], opsdata2[[input$cekgr_fill[[2]]]], 
                                       opsdata2[[input$cekgr_fill[[3]]]], opsdata2[[input$cekgr_fill[[4]]]],
                                       opsdata2[[input$cekgr_fill[[5]]]], sep = "*")
        }
        
      }else opsdata2$ivar <- interaction(opsdata2[[input$cekgr_fill]], sep = "*")
      
      ggplot(data= opsdata2, aes(x=reorder(GUDANG,KUANTUM/1000), y=KUANTUM/1000, 
                                 #fill=interaction(.data[[input$cekgr_fill[[1]]]], .data[[input$cekgr_fill[[2]]]], sep = "*")
                                 fill=as.factor(ivar)
      )) + 
        geom_col() + coord_flip() +
        scale_y_continuous(labels = unit_format(unit = "Ton")) +
        labs(x="",y="",fill="") + 
        theme_clean() + theme(legend.position = "top") 
      
    })
    
  })
  
  
})

shinyApp(ui = ui, server = server)

output

YBS
  • 19,324
  • 2
  • 9
  • 27
  • If you want to test my code, run the code and check all options in GUDANG. Check Beras and Ketan in KOMODITAS. Check 2019 and 2020 in TAHUN. Check JENIS and TAHUN in FILL GRAFIK. – deny1110 Feb 15 '21 at 14:06
  • Wow, it works. Thank you. I have a new questions: 1. What if I have more choices at FILL GRAFIK boxes rather than two. Should I add more code or argument at 'interaction()' ? 2. What if I have 5 options/choices in FILL GRAFIK, but I only want to make 3-variable interaction bar plot, so there are two choices unchecked, should I change the code again? How to make the code automatically detect and run without changing the argument/code in interaction() ? I mean, the code has a flexibility, and give user a freedom to determine how many interaction he/she will build without changing the code. – deny1110 Feb 15 '21 at 17:10
  • To YBS, thank you. I'll keep that in mind. – deny1110 Feb 15 '21 at 17:15
  • To YBS, thank you.It works well. I think it is enough to fulfill my need. – deny1110 Feb 16 '21 at 13:09
  • @deny1110, It is considered polite to accept an answer that has answered your OP. This helps others who are looking for a solution for the same/similar query. Furthermore, people may be willing to help you in your future queries. – YBS Feb 16 '21 at 13:52
  • To YBS , I've accepted your answer. Very useful. Thank you. – deny1110 Feb 16 '21 at 14:07