简体   繁体   中英

R Shiny Density Plots

I'm doing a project where we must create an R Shiny app that displays data. I have four quantitative variables (personal, social, weight, and eating). I want to have 4 density plots overlaying each other for each year in school and each gender when those are specified in the app. The density plots will not show up and no matter what I do they don't. Any advice would be so helpful!

library(shiny)
library(ggplot2)
library(purrr)
library(dplyr)

#plotting theme for ggplot2
.theme<- theme(
  axis.line = element_line(colour = 'gray', size = .75),
  panel.background = element_blank(),
  plot.background = element_blank()
)


# UI for app
ui<-(pageWithSidebar(
  # title
  headerPanel("Select Options for Body Image and Disordered Eating Among UW-Madison Students"),

  #input
  sidebarPanel
  ( # Input: Select what to display
  selectInput("gender", "Gender:",
                  choices = c("Female", 
                            "Male",
                            "Nonbinary", 
                            "Do not care to say"),
                  selected = "Female"),
    selectInput("school", "Year in School:",
                  choices = c("First Year", 
                            "Second Year",
                            "Third Year",
                            "Fourth Year"),
                  selected = "First Year")),
  mainPanel(plotOutput("densityplot"))
  )
)


# --------------------------------------------SERVER---------------------------------------------
server<-(function(input, output){
  output$plot <- renderUI({
    plotOutput("p")
    
    data = switch(input$gender,
                  "Female"="Female", 
                  "Male"= "Male",
                  "Nonbinary"= "Nonbinary", 
                  "Do not care to say" = "Do not care to say")  
    data = switch(input$school,
                  "First Year"="First Year", 
                  "Second Year"= "Second Year",
                  "Third Year"= "Third Year", 
                  "Fourth Year" = "Fourth Year")    
    data = switch(output$var,
                  "Personal"= cleandatafull$personal, 
                  "Social"= cleandatafull$social,
                  "Weight"= cleandatafull$weight, 
                  "Eating" = cleandatafull$eating)
    
     output$densityplot<-renderPlot({
      
      ggplot(cleandatafull, aes(x=output$var)) +
        geom_density(adjust=1.5, alpha=.4)  })
 # There is something going wrong here with the density plot and I just want something to show up so I can fix it to look how I want it to.
     
  })
  })
  


shinyApp(ui, server)

I don't have access to your data, but I have an idea on what's causing your plot not to appear in your code. In short, your plot code is never run, which is why you see nothing... and even if it did run, you'll probably get an error as written.

Why do you see nothing?

The structure of your server code is as follows:

server <-...
  output$plot <- renderUI({...
    plotOutput("p")

    output$densityplot <- renderPlot({...})
  })

The ui names only one output function, which would be output$densityplot . This part is never run, because it's inside of output$plot , which isn't found referenced anywhere in the UI. That's why you see nothing. All the code in output$plot will never run, since there is no output object referenced in ui by that name.

If you pull output$densityplot outside of output$plot , it will run, but you'll definitely get errors, as you reference for the x axis aesthetic aes(output$var) . You reference an output object, that would be inside of the server function, and therefore not in the ui .

How do you fix this?

Honestly, it's a bit too much to fix this specifically, and you have not shared data. I can show you a working example of how I would approach your general question. This is to say, it seems you're looking to change or filter the data shown in a plot based on UI elements selected by the user.

There are a few approaches you can use for this, but the general idea I like to use is to create a reactive function that outputs a data frame that will be used for plotting. Inside the reactive function, I'd put all the elements I may want to use for filtering a dataset, and then the returned data frame from the reactive function is used in the renderPlot() function associated with the plotOutput() object named in the ui .

In the following example, I'm creating an app to create density curves for the diamonds dataset. I give a dropdown to select the x axis, and then 3 other dropdowns that work to allow filtering of the dataset. I've also added some logic and functionality to allow for not filtering the dataset (default) when the user selects "All" in each of these.

Some final notes here: I use aes_string(input$s_axis) in place of aes(...) . The reason is that the output obtained from input$s_axis will be a character type, not the name of the column. You use get() and aes() , but aes_string() is a bit simpler here and works fine. Secondly, I often find it's generally better to explicitly print() the plot inside of renderPlot() , although it's not strictly required.

library(shiny)
library(ggplot2)
library(dplyr)
library(tidyr)


ui <- pageWithSidebar(
  headerPanel('Example of Filtering a Plot'),
    sidebarPanel(
      h3("Filters"),
      selectInput("s_color", label="Color:", choices = c("All", as.character(unique(diamonds$color)))),
      selectInput("s_cut", label="Cut:", choices=c("All", as.character(unique(diamonds$cut)))),
      selectInput("s_clarity", label="Clarity:", choices=c("All", as.character(unique(diamonds$clarity)))),
      br(),
      selectInput("s_axis", label="X Axis:", choices=c("carat","price", "depth", "table"))
    ),
    mainPanel(plotOutput('dazzle'))
)

server <- function(input, output) {
  
  glittering_diamonds <- reactive({
    d <- diamonds
    if(input$s_color != "All")
      d <- d %>% dplyr::filter(color==input$s_color)
    if(input$s_cut != "All")
      d <- d %>% dplyr::filter(cut==input$s_cut)
    if(input$s_clarity != "All")
      d <- d %>% dplyr::filter(clarity==input$s_clarity)
    return(d)
  })
    
  output$dazzle <- renderPlot({
    p <- ggplot(glittering_diamonds(), aes_string(x=input$s_axis)) +
      geom_density(fill='blue', alpha=0.2) +
      theme_classic()
    print(p)
  })
}

shinyApp(ui = ui, server = server)

Use that as some inspiration and good luck with your project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM