Home > Enterprise >  Having trouble implementing a for and while loop and how to add multiple outputs to be displayed in
Having trouble implementing a for and while loop and how to add multiple outputs to be displayed in

Time:10-26

I am currently creating a RShiny website for a project that models the data for Murder, Assault and Rape in the United States. I've made significant progress so far but I am having trouble with two issues.

  1. I am attempting to implement a for or while loop as part of my project and I'm unable to get the output to be displayed when I run the app. I want the for/while loop to return the states that also shared a Low/Medium/High risk of crime in the form of a text "The other states which have a low/medium/high rate of crime are State1, State2, State3, etc". This is dependent on the state the user selected in the drop down box in the sidebar. I have had no luck in writing the code for this. I understand theres 100% easier ways to do this without a looping structure but my project requires me to use a for or while loop.

  2. How am I able to combine more than one output on a tab panel so that both outputs show. I want there to only be one "How safe is the State?" tab, but whenever I tried to combine both, no outputs would show on the tab.

library(shiny)
library(tidyverse)
library(ggplot2)

# Define UI for application that draws the graphs
ui <- fluidPage(
    
    # Application title
    titlePanel("Rate of Crime in United States"),
    p("Use the variable selector to refine your search!"),
    
    # Sidebar with widgets adjust server output
    sidebarLayout(
        sidebarPanel(
            checkboxGroupInput("display_var",
                               "Which Crime/s to Display?",
                               choices = c("Murder" = "Murder",
                                           "Assault" = "Assault",
                                           "Rape" = "Rape"),
                               selected = "Murder"
            ),
            
            sliderInput("bins",
                        "Number of bins (valid for Histogram chart only):",
                        min = 5,
                        max = 10,
                        value = 7
            ),
            
            selectInput(
                "search", "How safe is this state?", choices = (attributes(USArrests)$row.names), selected = NULL)
            
            
            ),
            
      
        
        # Create the tabs
        mainPanel(
            tabsetPanel(
                tabPanel("Bar Plot", plotOutput("barplot")),
                tabPanel("Histogram", plotOutput("distPlot")),
                tabPanel("How Safe is the State?", textOutput("howsafe")),
                tabPanel("How Safe is the State?pt2", textOutput("howsafe2"))
                
            )
        )
    ))
       

# Define server logic required to draw graphs
server <- function(input, output) {
    output$barplot <- renderPlot({
        
        marchoice <- req(input$display_var)
        sd <- setdiff(names(USArrests),marchoice)
        temp_df <- USArrests
        temp_df[,sd] <- 0
        
        counts <- temp_df$Murder   temp_df$Assault   temp_df$Rape
        names(counts) <- rownames(temp_df)
        barplot(counts, 
                main="Aggregate Sum of Crime in the United States",
                xlab="State",
                ylab="Frequency",las=2,col=rgb(0.2,0.4,0.6,0.6))
    })
#Transform numeric variables into categorical    
CategorisedMAR <- cut(USArrests$Murder   USArrests$Assault   USArrests$Rape, breaks=c(0,150,300,450), labels = c("Low", "Medium", "High"))
names(CategorisedMAR) <- attributes(USArrests)$row.names
st <- reactive(input$search)


    output$howsafe <- renderText({ 
        #if-else statement to state risk based on state selection
        if (CategorisedMAR[[input$search]] == "Low") {
            paste0(st(), " has a low rate of crime")
        } else if (CategorisedMAR[[input$search]] == "Medium") {
            paste0( st()," has a mid-level rate of crime")
        } else if (CategorisedMAR[[input$search]] == "High") {
            paste0( st(), " has a high rate of crime")
        }
        
       
        
    })
    
    output$howsafe2 <- renderText({
        for(value in CategorisedMAR) {
            if(value == "Low") {
                print(value)}
            }
            
        
        
        
        
    })
        
    
    
    output$distPlot <- renderPlot({
        
        #Create new data based on the selection
        USArrests2 <- 
            USArrests %>%
            select(!!input$display_var) %>% 
            mutate(cumulative_frequency = rowSums(across(where(is.numeric))))
        
        # Create plot - Show the cumulative frequency
        ggplot(USArrests2, aes(cumulative_frequency))   ggtitle("Histogram of Variable Frequency")  
            theme(plot.title = element_text(hjust = 0.5))   
            geom_histogram(bins = input$bins,
                           fill = rgb(0.2,0.4,0.6,0.6),
                           colour = "grey30")   
            
            #Create a new label based on what has been selected  
            xlab(str_c(input$display_var, collapse = " & "))  
            theme_minimal()
        
        
    })
    
    
}



# Run the application
shinyApp(ui = ui, server = server)

This is the code that I have built so far. I have also attached a photo detailing what I am trying to achieve for clarity. "reprex of what I am trying to achieve

I have spent countless days working on this and any help would be greatly appreciated. Thanks in advance!

CodePudding user response:

Perhaps this will do

library(shiny)
library(tidyverse)
library(ggplot2)
library(DT)

# Define UI for application that draws the graphs
ui <- fluidPage(

  # Application title
  titlePanel("Rate of Crime in United States"),
  p("Use the variable selector to refine your search!"),

  # Sidebar with widgets adjust server output
  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("display_var",
                         "Which Crime/s to Display?",
                         choices = c("Murder" = "Murder",
                                     "Assault" = "Assault",
                                     "Rape" = "Rape"),
                         selected = "Murder"
      ),

      sliderInput("bins",
                  "Number of bins (valid for Histogram chart only):",
                  min = 5,
                  max = 10,
                  value = 7
      ),

      selectInput( "search", "How safe is this state?", choices = (attributes(USArrests)$row.names), selected = NULL)
    ),

    # Create the tabs
    mainPanel(
      tabsetPanel(
        tabPanel("Bar Plot", plotOutput("barplot")),
        tabPanel("Histogram", plotOutput("distPlot")),
        tabPanel("How Safe is the State?", textOutput("howsafe"), br(),br(), textOutput("howsafe2"))

      )
    )
  ))


# Define server logic required to draw graphs
server <- function(input, output) {
  output$barplot <- renderPlot({

    marchoice <- req(input$display_var)
    sd <- setdiff(names(USArrests),marchoice)
    temp_df <- USArrests
    temp_df[,sd] <- 0

    counts <- temp_df$Murder   temp_df$Assault   temp_df$Rape
    names(counts) <- rownames(temp_df)
    barplot(counts,
            main="Aggregate Sum of Crime in the United States",
            xlab="State",
            ylab="Frequency",las=2,col=rgb(0.2,0.4,0.6,0.6))
  })
  #Transform numeric variables into categorical
  labels = c("Low", "Medium", "High")
  CategorisedMAR <- cut(USArrests$Murder   USArrests$Assault   USArrests$Rape, breaks=c(0,150,300,450), labels = labels)
  names(CategorisedMAR) <- attributes(USArrests)$row.names
  st <- reactive(input$search)

  output$howsafe <- renderText({
    #if-else statement to state risk based on state selection
    if (CategorisedMAR[[input$search]] == "Low") {
      paste0(st(), " has a low rate of crime")
    } else if (CategorisedMAR[[input$search]] == "Medium") {
      paste0( st()," has a mid-level rate of crime")
    } else if (CategorisedMAR[[input$search]] == "High") {
      paste0( st(), " has a high rate of crime")
    }
  })

  output$howsafe2 <- renderText({
    myvalue = CategorisedMAR[[input$search]]
    n <- length(CategorisedMAR)
    list_states <- c()

    for (i in 1:n){
      if (CategorisedMAR[[i]]==myvalue) list_states <- c(list_states,names(CategorisedMAR)[i])
    }
    mylist <- list_states[! list_states %in% st()]
    a <- paste0(c("The following states also had", tolower(labels[myvalue]),"rate of crime:"), collapse=" ")
    b <- paste0(paste(c(a,mylist), collapse=", "),".")
    aa <- gsub(":,",":", b)
    
    paste(aa)
  })

  output$distPlot <- renderPlot({

    #Create new data based on the selection
    USArrests2 <-
      USArrests %>%
      dplyr::select(input$display_var) %>%
      mutate(cumulative_frequency = rowSums(across(where(is.numeric))))

    # Create plot - Show the cumulative frequency
    ggplot(USArrests2, aes(cumulative_frequency))   ggtitle("Histogram of Variable Frequency")  
      theme(plot.title = element_text(hjust = 0.5))  
      geom_histogram(bins = input$bins,
                     fill = rgb(0.2,0.4,0.6,0.6),
                     colour = "grey30")  

      #Create a new label based on what has been selected
      xlab(str_c(input$display_var, collapse = " & "))  
      theme_minimal()

  })

}

# Run the application
shinyApp(ui = ui, server = server)
  • Related