library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.4.0      ✔ purrr   1.0.0 
## ✔ tibble  3.1.8      ✔ dplyr   1.0.10
## ✔ tidyr   1.2.1      ✔ stringr 1.5.0 
## ✔ readr   2.1.3      ✔ forcats 0.5.2 
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.2.3
library(shiny)
library(shinythemes)
## Warning: package 'shinythemes' was built under R version 4.2.3
library(ggplot2)
library(dplyr)
library(viridis)
## Loading required package: viridisLite
# Example of using a URL for a GitHub-hosted raw file
url <- "https://raw.githubusercontent.com/ConnorLandreth/Spring24_Data_Viz/ConnorLandreth/Salary_Data.csv"
SD <- read.csv(url)


avgsal <- SD %>% 
  group_by(Age) %>% 
  summarize(avg_salary = mean(Salary)) %>% 
  filter(!(Age %in% c(26, 31, 36)))

avgyr <- SD %>% 
  group_by(Years.of.Experience) %>% 
  summarize(avg_salary = mean(Salary)) %>% 
  filter(!(Years.of.Experience %in% c(6, 8)))





# Identify the top 8 job titles
top_job_titles <- SD %>%
  group_by(Job.Title) %>%
  summarize(count = n()) %>%
  arrange(desc(count)) %>%
  slice_head(n = 6) %>%
  pull(Job.Title)

# Filter the data for the top 8 job titles
filtered_data <- SD %>%
  filter(Job.Title %in% top_job_titles)



SD <- SD %>%
  mutate(Education.Level = case_when(
    grepl("Bachelor", Education.Level, ignore.case = TRUE) ~ "Bachelor's",
    grepl("Master", Education.Level, ignore.case = TRUE) ~ "Master's",
    TRUE ~ as.character(Education.Level)
  ))




SD$Education.Level <- factor(SD$Education.Level, levels = c("PhD", "Master's", "Bachelor's", "High School"))

# Filter the data for the top 8 job titles
filtered_data <- SD %>%
  filter(Job.Title %in% top_job_titles)
# List of state names
states <- c("alabama", "alaska", "arizona", "arkansas", "california", "colorado", "connecticut", "delaware", "florida", "georgia", 
            "hawaii", "idaho", "illinois", "indiana", "iowa", "kansas", "kentucky", "louisiana", "maine", "maryland", "massachusetts", 
            "michigan", "minnesota", "mississippi", "missouri", "montana", "nebraska", "nevada", "new hampshire", "new jersey", 
            "new mexico", "new york", "north carolina", "north dakota", "ohio", "oklahoma", "oregon", "pennsylvania", "rhode island", 
            "south carolina", "south dakota", "tennessee", "texas", "utah", "vermont", "virginia", "washington", "west virginia", 
            "wisconsin", "wyoming")

# Assign a random state to each row in SD
set.seed(123)  # Set seed for reproducibility
SD$state <- sample(states, size = nrow(SD), replace = TRUE)

# Convert state names to lowercase for consistency
SD$state <- tolower(SD$state)

# Check the structure of SD to ensure the 'state' column is created correctly
str(SD)
## 'data.frame':    6704 obs. of  7 variables:
##  $ Age                : int  32 28 45 36 52 29 42 31 26 38 ...
##  $ Gender             : chr  "Male" "Female" "Male" "Female" ...
##  $ Education.Level    : Factor w/ 4 levels "PhD","Master's",..: 3 2 1 3 2 3 2 3 3 1 ...
##  $ Job.Title          : chr  "Software Engineer" "Data Analyst" "Senior Manager" "Sales Associate" ...
##  $ Years.of.Experience: num  5 3 15 7 20 2 12 4 1 10 ...
##  $ Salary             : int  90000 65000 150000 60000 200000 55000 120000 80000 45000 110000 ...
##  $ state              : chr  "new mexico" "iowa" "indiana" "arizona" ...
# Convert state names to lowercase for consistency
SD$state <- tolower(SD$state)

# Calculate average salary by state
average_salary <- SD %>%
  group_by(state) %>%
  summarise(average_salary = mean(Salary, na.rm = TRUE))

# Map of US states
map_us <- map_data("state")

# Merge average salary data with the map data
merged_data <- left_join(map_us, average_salary, by = c("region" = "state"))

Final Dashboard for Presentation

ui <- fluidPage(
  theme = shinytheme("journal"),
  titlePanel("Corporate Careers Summary Dashboard (US)"),
  fluidRow(
    column(6, plotOutput("educationLevelPlot")),
    column(6, plotOutput("salaryMapPlot"))
  ),
  fluidRow(
    column(6, plotOutput("salaryPlot")),
    column(6, plotOutput("ageExperiencePlot"))
  )
)

server <- function(input, output, session) {
  
  # Global theme setting
  theme_set(theme_minimal(base_size = 14) + theme(
    axis.text = element_text(face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1)
  ))
  
  # Define a consistent color palette
  color_palette <- c("0-49,999" = "purple4", "50,000-99,999" = "royalblue", "100,000-149,999" = "turquoise4", "150,000+" = "yellow4")

  # Visualization for One Categorical & One Numerical - multi
  output$salaryPlot <- renderPlot({
    top_job_titles <- SD %>%
      group_by(Job.Title) %>%
      summarize(count = n()) %>%
      arrange(desc(count)) %>%
      slice_head(n = 6) %>%
      pull(Job.Title)

    filtered_data <- SD %>%
      filter(Job.Title %in% top_job_titles)

    ggplot(filtered_data, aes(x = Job.Title, y = Salary)) +
      geom_boxplot(fill = "turquoise4", color = "black") +
      labs(title = "Salaries for Top 6 Job Titles",
           subtitle = "United States, 2022",
           caption = "Source: Kaggle",
           x = "Job Title", y = "Salary") +
      annotate("text", x = 'Senior Project Engineer', y = 50000, label = "Mean compensation for top professions: $149,833", hjust = 1.1, vjust = 1.1, size = 4, colour = "red")
  })

  # Visualization for Two Numerical - multi with salary bins
  output$ageExperiencePlot <- renderPlot({
    SD$SalaryBins <- cut(SD$Salary,
                         breaks = c(0, 50000, 100000, 150000, Inf),
                         labels = c("0-49,999", "50,000-99,999", "100,000-149,999", "150,000+"),
                         include.lowest = TRUE)
    
    ggplot(SD, aes(x = Age, y = Years.of.Experience, color = SalaryBins)) +
      geom_point(size = 3) +
      labs(title = "Age vs. Years of Experience",
           subtitle = "United States, 2022",
           caption = "Source: Kaggle",
           x = "Age", y = "Years of Experience", color = "Salary Range") +
      scale_color_manual(values = color_palette)
  })

  # Adjusted Visualization for One Categorical Variable - uni
  output$educationLevelPlot <- renderPlot({
    data <- SD %>% filter(!is.na(Education.Level))
    max_count <- max(table(SD$Education.Level))  # Calculate the maximum count
    ggplot(data, aes(x = Education.Level)) +
      geom_bar(fill = "turquoise4", color = "black") +
      geom_text(stat = 'count', aes(label = ..count..), vjust = -1.5, color = "black") +  # Display count above bars
      labs(title = "Distribution of Education Levels",
           subtitle = "United States, 2022",
           caption = "Source: Kaggle",
           x = "Education Level", y = "") +
      ylim(0, max_count * 1.2) +  # Extend the y-axis to fit labels
      annotate("text", x = "PhD", y = 2500, label = "45.1% of degree holders have a bachelor's degree", size = 3.25, colour = "red")
  })
  
  # Plotting the map with fill color based on average salary
  output$salaryMapPlot <- renderPlot({
    ggplot(merged_data, aes(x = long, y = lat, group = group, fill = average_salary)) +
      geom_polygon(color = "white", size = 0.1) +
      scale_fill_viridis() +
      labs(title = "Average Salary by State",
           subtitle = "United States, 2022",
           caption = "Source: Kaggle",
           fill = "Average Salary") +
      coord_map()
  })
}

# Running the app
shinyApp(ui = ui, server = server)
## PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
Shiny applications not supported in static R Markdown documents