Code for producing the SoJSM Employment Outlook.
# Instaling and loading required packages
if (!require("tidyverse"))
install.packages("tidyverse")
if (!require("plotly"))
install.packages("plotly")
library(tidyverse)
library(plotly)
library(scales)
options(scipen = 999)
# Reading data downloaded from
# https://data.bls.gov/projections/occupationProj
AllData <- read.csv("Employment Projections.csv")
BAjobs <- AllData %>%
filter(
Typical.Entry.Level.Education == "Bachelor's degree" &
Work.Experience.in.a.Related.Occupation %in% c("None", "Less than 5 years"))
# Date standardization and data cleaning
BAjobs$Pay <- as.numeric(gsub(",", "", BAjobs$Median.Annual.Wage.2023))
BAjobs$Openings <- BAjobs$Occupational.Openings..2023.2033.Annual.Average * 1000
BAjobs$Occupation.Code <- gsub('"',"",BAjobs$Occupation.Code)
BAjobs$Occupation.Code <- gsub('=',"",BAjobs$Occupation.Code)
# Computing median wages and openings
MedianPay <- median(BAjobs$Pay)
MedianOpenings <- median(BAjobs$Openings)
# Filtering for media jobs
# using SOCS codes. See:
# https://www.bls.gov/oes/current/oes_stru.htm
# Filtering for SoJSM jobs
Mediajobs <- BAjobs %>%
filter(Occupation.Code %in% c("11-2032",
"11-2033",
"11-2011",
"27-3041",
"27-3042",
"27-3043",
"27-3031",
"27-3023",
"27-1024",
"15-1254",
"15-1255",
"27-2012",
"27-3011",
"27-4032",
"27-4031"))
# Shortening SOC job titles
Mediajobs$Job <- str_split_i(Mediajobs$Occupation.Title," *", 1)
# Formatting media pay data
Job <- "Median"
Pay <- MedianPay
PayLine <- data.frame(Job,Pay)
PayChart <- Mediajobs %>%
select(Job,Pay) %>%
rbind(PayLine) %>%
arrange(desc(Pay))
# Formatting media job openings data
Job <- "Median"
Openings <- MedianOpenings
OpeningsLine <- data.frame(Job,Openings)
OpeningsChart <- Mediajobs %>%
select(Job,Openings) %>%
rbind(OpeningsLine) %>%
arrange(desc(Openings))
# Cleanup
rm(AllData,
BAjobs,
Mediajobs,
OpeningsLine,
PayLine,
Job,
MedianOpenings,
MedianPay,
Openings,
Pay)
# Graphing media pay data
PayChart <- PayChart %>%
mutate(Dollars = dollar(Pay))
PayFig <- PayChart %>%
mutate(Job = forcats::fct_reorder(Job, Pay)) %>%
ggplot(aes( x = Pay, y = Job)) +
geom_col(aes(fill = Job != "Median")) +
scale_fill_manual(values = c("#FF7F3E","#384B70"), guide = "none")+
geom_text(aes(label = Dollars),
color = "white",
hjust = 1, nudge_x = -.1) +
theme(
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
axis.title.y = element_blank(),
panel.background = element_blank())
PayFig
# Graphing media openings data in thousands
OpeningsChart <- OpeningsChart %>%
mutate(Openings = Openings / 1000)
OpeningsFig <- OpeningsChart %>%
mutate(Job = forcats::fct_reorder(Job, Openings)) %>%
ggplot(aes( x = Openings, y = Job,)) +
geom_col(aes(fill = Job != "Median")) +
scale_fill_manual(values = c("#FF7F3E","#384B70"), guide = "none")+
geom_text(aes(label = Openings),
color = "white",
hjust = 1, nudge_x = -.1) +
theme(
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
axis.title.y = element_blank(),
panel.background = element_blank())
OpeningsFig