Home > database >  Shiny R: Align objects vertically create output that lets choose between percentages and quantitie
Shiny R: Align objects vertically create output that lets choose between percentages and quantitie

Time:07-02

First of a small disclaimer: This is my first ever asked question and I am not very experienced with shiny or "R" since this is only for a small project :)

How it is:

I made histograms that show the same data in percentages and quantity. Currently its looking like this:

The current state of my histograms

What I am trying to do now:

  1. Instead of having 2 histograms vertically I want an input that lets me choose, if I want the data to be shown in percentages or quantities.

  2. I want to add text next to the histogram to describe the data

  3. I want them to align horizontally like this: INPUT - HISTOGRAM - TEXT

How my code is looking up to this point:

ui <- fluidPage(
      theme = bs_theme(version = 4, bootswatch = "minty"),
      titlePanel("Titanic"),
      sidebarLayout(
        sidebarPanel(),
        mainPanel(
          img(src = "titanicPic.jpg",height = 182, width = 520))),
          p(""),
          h4("", style = "font-family: 'times';,font-si16pt"),
          h6("", style = "font-family: 'times';,font-si16pt"),
          h6("", style = "font-family: 'times';,font-si16pt"),
      tabsetPanel(
        tabPanel("x", tableOutput("")), 
        tabPanel("y", verbatimTextOutput("")), 
        tabPanel("z", tableOutput(""))),
      
      
      plotOutput(outputId = "ex1", width = 400),
      plotOutput(outputId = "ex2", width = 400)
     
server <- function(input, output) {
  
  output$ex1 <- renderPlot({
    ggplot( survivalMutate,
            aes(x = Sex, fill = Status))  
      ggtitle("Wer hat überlebt in %?") 
      geom_bar(position = "fill") 
      scale_fill_manual(values = c("grey24", "snow"))  
      labs(y= "Proportion")
  })
  
  output$ex2 <- renderPlot({
    ggplot(survivalMutate,
           aes(x = Sex,
               fill = Status))   
      geom_bar(position = "stack")  
      ggtitle("Wer hat überlebt in anzahl?") 
      scale_fill_manual(values = c("grey24", "snow")) 
      labs(y= "Anzahl")
  })


shinyApp(ui = ui, server = server)

In ui you can see in the last two rows that im making the plotOutputs for the two histograms, that I created in the server-part. These take the same data but differ in how they show it (Percentages vs. quantities).

I'd be super thankful for any advice, links to look it up, tips and more. Thank you a lot If you've read to this point and have a nice day/evening/night!

CodePudding user response:

Welcome! I hope your journey with Shiny and R continues to go well. You have three questions, selecting which plot, adding text next to the histogram, and aligning horizontally. There are plenty of ways to do each of these.

The way I chose to select which plot is using conditionalPanel() and selectInput(). conditionalPanel() checks the selectInput(), and will display only a different graph depending on the choice. An alternative would be using the shinyjs package, and the hide() and show() functions. Here is a link to conditionalpanels: https://shiny.rstudio.com/reference/shiny/1.6.0/conditionalPanel.html And here is some info on the shinyjs package: https://cran.r-project.org/web/packages/shinyjs/vignettes/shinyjs-example.html

For placing text next next to the histogram, and then aligning things horizontally, I used column(). Each row has a width of 12 from my understanding, and so you can select how much room each column takes within that row, so in this case I made put the selectInput() in column(width = 2), since it doesn't need much space, then I put the plots and the extra text in the remaining 10, using column(width = 10). Within a column, that space can also be occupied by a width of 12. In each conditionalPanel(), I made the plot itself a width of 4, and the text a width of 8. Here is a link to some info on columns: https://shiny.rstudio.com/reference/shiny/0.14/column.html

Note that I blocked out a number of features in your code because they weren't necessary to answer the questions, and I just used the built in mtcars data since I don't have your dataset. Here is the code I used.

library(shiny)
library(ggplot2)

ui <- fluidPage(
  # theme = bs_theme(version = 4, bootswatch = "minty"), #Not needed for the question
  titlePanel("Titanic"),
  sidebarLayout(
    sidebarPanel(),
    mainPanel(
      # img(src = "titanicPic.jpg",height = 182, width = 520) #Not needed for the question
    )
  ),
  # p(""), #Not needed for the question
  # h4("", style = "font-family: 'times';,font-si16pt"),
  # h6("", style = "font-family: 'times';,font-si16pt"),
  # h6("", style = "font-family: 'times';,font-si16pt"),
  # tabsetPanel(
  #   tabPanel("x", tableOutput("")), 
  #   tabPanel("y", verbatimTextOutput("")), 
  #   tabPanel("z", tableOutput(""))),
  column(width = 2,
         selectInput("PlotChoose", "Plot by proportion or Anzahl?", choices = c("Proportion", "Anzahl"))),
  column(width = 10,
         conditionalPanel("input.PlotChoose == 'Proportion'",
                          column(width = 4, 
                                 plotOutput(outputId = "ex1", width = 400)),
                          column(width = 8,
                                 h4("This is some text that to describe about this proportion plot")
                          )
         ),
         conditionalPanel("input.PlotChoose == 'Anzahl'",
                          column(width = 4, 
                                 plotOutput(outputId = "ex2", width = 400)),
                          column(width = 8,
                                 h4("This is some text that to describe about this Anzahl plot")
                          )
         )
  )
)

server <- function(input, output) {
  
  output$ex1 <- renderPlot({
    ggplot( mtcars,
            aes(x = factor(gear), fill = factor(cyl)))  
      ggtitle("Wer hat überlebt in %?") 
      geom_bar(position = "fill") 
      scale_fill_manual(values = c("grey24", "snow", "pink"))  
      labs(y= "Proportion")
  })
  
  output$ex2 <- renderPlot({
    ggplot(mtcars,
           aes(x = factor(gear),
               fill = factor(cyl)))   
      geom_bar(position = "stack")  
      ggtitle("Wer hat überlebt in anzahl?") 
      scale_fill_manual(values = c("grey24", "snow", "pink")) 
      labs(y= "Anzahl")
  })
}


shinyApp(ui = ui, server = server)

I hope this gives you ideas on how to move forward, and I wish you the best of luck in your future endeavors!

CodePudding user response:

I adjusted Silentdevildoll's answer to do exactly what I was looking for:

fluidRow(
        column(width = 3,
               selectInput("PlotChoose", "Ansicht: Proportion oder Anzahl?", choices = c("Proportion", "Anzahl"))),
        column(width = 4,
               conditionalPanel("input.PlotChoose == 'Proportion'",
                                column(width = 8, 
                                       plotOutput(outputId = "ex3", width = 400)
                                )
               ),
               conditionalPanel("input.PlotChoose == 'Anzahl'",
                                column(width = 8, 
                                       plotOutput(outputId = "ex4", width = 400)))),
        column(width = 5, h6("TEXT HERE")))

This goes into ui <- fluidPage(...)

Thanks again to @Silentdevildoll!

  • Related