Overview

The Task

There have been growing concerns about gender pay equality in university settings.


Syracuse settles a class action lawsuit about pay equity

Syracuse University has settled a class-action lawsuit and will pay more than $3.7 million to resolve allegations from five female professors who claimed the school’s compensation and promotion policies and practices discriminated against women.


As a result, the Arizona Board of Regents has hired you to create a reporting system so that it can monitor the problem. You need to build a system to automate the process of generating reports when a new year of data becomes available.

Project Overview

In order to build a reporting system you will need to create the following:

  1. Custom functions for cleaning and visualizing the salary data (utils.R).
  2. A template that contains the report instructions / sections (salary-report.rmd).
  3. A batch script that will let you run all of the reports (batch.R).

Here are some example files:

And here are examples of the reports generated (note that you would change the knit options to echo=FALSE so code is hidden in the final report, but it’s included here for demo purposes):

Before you go on to next steps, download these three files do your local working directory. Open batch.R in a regular R console and try running the reports to create the HTML files.

You may need to install pandoc if it is not already on your machine and update the rmarkdown package.

In the subsequent steps you will:

  1. Develop the rest of the custom functions for the full report and add them to the utils.R file.
  2. Update the salary-report.rmd template by adding the new sections described below.
  3. Gather the URLs for 2018, 2017, and 2016 data and add them to the batch processing file to generate three more years of reports.

The project has 3 parts:

  • Part I: Create Custom Functions
  • Part II: Build a Loop to Add All Departments to the Report
  • Part III: Refine the Report Template and Batch Processing File



Packages

You will likely need to install the gender and genderdata packages from GitHub directly:

install.packages("remotes") # if necessary
remotes::install_github("lmullen/gender")
remotes::install_github("lmullen/genderdata")

Be sure to never include install commands in an RMD doc unless you include the chunk argument eval=F because it will create errors while knitting.

If you are getting errors while installing genderdata you might need to download the tarball (zipped package) from the link and install it using the local (instead of CRAN or GitHub option):


library( dplyr )
library( pander )
library( knitr )
library( gender )

You will create helper functions to clean and process data using instructions below. These will all be stored in a “utilities” file called utils.R and loaded into your report template using the source command:

source( "utils.R" )

Source commands typically go in the same chunk as load package commands.

Part I

Step 1: Data

We will be using the ASU salaries database distributed by the The State Press, and Arizona newspaper:

https://www.statepress.com/article/2017/04/spinvestigative-salary-database

Since ASU is a public university salary data is in the public domain, though the university doesn’t release it directly to the public. The State Press likely does a Freedom of Information request each year, cleans the data, and adds it to their online database of salaries (a google spreadsheet with several tabs):

https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/edit#gid=1335284952

We can use information embedded in this web link to create a convenient import command in R:

# WE NEED THE FORMAT: 
# https://docs.google.com/spreadsheets/d/<KEY>/export?gid=<GID>&format=csv
#
# where <KEY> and <GID> can be obtained from the base URL:
# https://docs.google.com/spreadsheets/d/<KEY>/edit#gid=<GID>

URL <- 'https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/export?gid=1335284952&format=csv'
d <- read.csv( URL )
head( d ) %>% pander()
Table continues below
Calendar.Year Full.Name Job.Description
2020 ABBASI, Mohammad Research/Lab Assistant
2020 ARQUIZA, Jose Maria Reynaldo Apollo Lecturer
2020 Aaberg, Kelsea Student Support Specialist
2020 Abadjivor, Enyah Project Manager
2020 Abayesu, Precious Management Intern
2020 Abbas, James Assoc Professor
Department.Description Salary FTE
Sch Biological & Hlth Sys Engr $35,090.00 100
Sch Biological & Hlth Sys Engr $71,400.00 100
Admission Services $36,000.00 100
CASGE Tempe $64,000.00 100
Health & Clinical Partnerships $20,800.00 50
Sch Biological & Hlth Sys Engr $107,195.00 100

Step 2: Parse First Name

Write a name parsing function called get_first_name() that will take a Full.Name as the argument and return only the first name.

Note that the Full.Name variable has the format: LAST_NAME, FIRST_NAME MIDDLE_NAME

# Example of a working get_first_name() function:
top.25 <- head( d$Full.Name,25 )
first.25 <- get_first_name( name=top.25 )

data.frame( top.25, first.25 ) %>% pander()
top.25 first.25
ABBASI, Mohammad Mohammad
ARQUIZA, Jose Maria Reynaldo Apollo Jose
Aaberg, Kelsea Kelsea
Abadjivor, Enyah Enyah
Abayesu, Precious Precious
Abbas, James James
Abbaszadegan, Morteza Morteza
Abbe, Scott Scott
Abbl, Norma Norma
Abbott, Joshua Joshua
Abbott, Joshua Joshua
Abdollahi, Amir Amir
Abdou, Olgeanna Olgeanna
Abdurhman, Abdurazak Abdurazak
Abel, John John
Abele, Kelsey Kelsey
Aberle, James James
Abhyankar, Aditya Aditya
Abi Karam, Karam Karam
AbiNader, Millan Millan
Aboalam, Safaa Safaa
Abraha, Naomi Naomi
Abramchuk, Mykola Mykola
Abrams, Cristen Cristen
Abrams, Kristen Kristen

Note, the name format changes slightly between years. Specifically, some years use a comma+space as the delimiter between last name and the rest of the string. Other years use only a comma.

Make sure your name parser can handle both cases. If you use the comma as a split value, for example, you can always drop the extra space later using the trim white space function trimws().

### 2019 DATA
 [65] "Adelman,Madelaine"        "Adler,Patricia"          
 [67] "Adrian,Ronald"            "Adusumilli,Sesha Chandra"
 [69] "Afanador Pujol,Angelica"  "Affolter,Jacob"          
 [71] "Afsari Mamaghani,Sepideh" "Aganaba,Timiebi"     

### 2020 DATA
[1] "ABBASI, Mohammad"                    "ARQUIZA, Jose Maria Reynaldo Apollo"
[3] "Aaberg, Kelsea"                      "Abadjivor, Enyah"                   
[5] "Abayesu, Precious"     

Here is some test data that includes both formats if you want to see if your function works for all years of data:

x <- 
c("ABBASI, Mohammad", "ARQUIZA,Jose Maria Reynaldo Apollo", 
"Aaberg,Kelsea", "Abadjivor, Enyah", "Abayesu,Precious", "Abbas, James", 
"Abbaszadegan, Morteza", "Abbe,Scott", "Abbl,Norma", "Abbott, Joshua" )

# Note the difference here: 

x.list <- strsplit( x, ", " )               # split on last name
COMMA.SPACE <- sapply( x.list, function(x){x[2]} )   # return second element

x.list <- strsplit( x, "," )                # split on last name
COMMA.ONLY <- sapply( x.list, function(x){x[2]} )   # return second element

cbind( COMMA.SPACE, COMMA.ONLY )
##       COMMA.SPACE COMMA.ONLY                  
##  [1,] "Mohammad"  " Mohammad"                 
##  [2,] NA          "Jose Maria Reynaldo Apollo"
##  [3,] NA          "Kelsea"                    
##  [4,] "Enyah"     " Enyah"                    
##  [5,] NA          "Precious"                  
##  [6,] "James"     " James"                    
##  [7,] "Morteza"   " Morteza"                  
##  [8,] NA          "Scott"                     
##  [9,] NA          "Norma"                     
## [10,] "Joshua"    " Joshua"

Pay attention to what happens if we ignore spaces. Which names are ignored by the gender package?

# library( gender )
gender( COMMA.ONLY  )

What happened to Jose? Note how the gender package deals with compound first names:

gender( c( "jose", "jose maria", "josemaria" ) )

Since we can’t tell the difference between a compound first name (two first names) and a first name + middle name in this dataset we can use the first name only since it will provide the same information about the gender of the individual.

get_first_name( "Adusumilli, Sesha Chandra" ) --> "Sesha" 

Step 3: Add Gender to the Dataset

The database does not provide the gender of the employees, but that’s alright because we can code these ourselves once we have first names isolated.

The gender package allows us to query a database of US birth certificates to see the most likely gender of someone with a specific first name.

library( gender )

# need to save first names for the merge 
d$first.name <- get_first_name( name=d$Full.Name )

# create a list of unique first names in the data 
unique.first.names <- unique( d$first.name )

# get gender data from US Social Security Admin 
gen <- gender( unique.first.names )
head( gen ) %>% pander()
name proportion_male proportion_female gender year_min year_max
Aaron 0.9918 0.0082 male 1932 2012
Abba 1 0 male 1932 2012
Abbey 0.0017 0.9983 female 1932 2012
Abbie 0.0088 0.9912 female 1932 2012
Abby 0.003 0.997 female 1932 2012
Abdel 1 0 male 1932 2012

You then need to add gender to the salary dataset by merging the gender data frame with the salary data using first names as the unique key. Make sure you do not drop observations from the salary database.

Notes on Data Joins

If the name was not found in the US names database the gender will be coded as NA. After you complete the data join, replace all of the missing cases with the label “uncoded” so that we don’t end up with NAs in tables.

# d <- merge( d, gen, ... )
d$gender[ is.na(d$gender) ] <- "uncoded"
d$gender <- factor( d$gender, levels=c("male","female","uncoded") )

Create a function called add_gender() that calls the get_first_name() function, filters the vector of first names into a vector of unique first names, builds a gender table for the names, adds the gender fields to the data frame through a merge, then recodes NA values as “uncoded”.

Step 4: Standardize Job Titles

We are interested in five categories of job titles but the job description field is not standardized across the university. Here is a quick crosswalk, likely missing some cases and with some errors but good enough for a first pass.

Convert these steps into a add_titles() function that adds the new variable title to the existing data frame.

title <- rep( "", nrow(d) )
title[ grepl( "^Asst Professor$", d$Job.Description ) ]  <- "Assistant Professor"
title[ grepl( "^Assoc Professor$", d$Job.Description ) ] <- "Associate Professor"

title[ grepl( "^Professor$", d$Job.Description ) ]            <- "Full Professor"
title[ grepl( "Regents Professor", d$Job.Description ) ]      <- "Full Professor"
title[ grepl( "President's Professor", d$Job.Description ) ]  <- "Full Professor"

title[ grepl( "^Postdoctoral Research Scholar$", d$Job.Description ) ]   <- "Researcher"
title[ grepl( "Research Specialist", d$Job.Description ) ]               <- "Researcher"
title[ grepl( "Research Analyst", d$Job.Description ) ]                  <- "Researcher"
title[ grepl( "Postdoctoral Scholar", d$Job.Description ) ]              <- "Researcher"
title[ grepl( "Research Scientist", d$Job.Description ) ]                <- "Researcher"
title[ grepl( "Research Professional", d$Job.Description ) ]             <- "Researcher"
title[ grepl( "Research Professor", d$Job.Description ) ]                <- "Researcher"

title[ grepl( "^Instructor$", d$Job.Description ) ]           <- "Teaching Faculty"
title[ grepl( "Clinical .+ Professor", d$Job.Description ) ]  <- "Teaching Faculty"
title[ grepl( "Lecturer$", d$Job.Description ) ]              <- "Teaching Faculty"
title[ grepl( "^Lecturer Sr$", d$Job.Description ) ]          <- "Teaching Faculty"
title[ grepl( "^Principal Lecturer$", d$Job.Description ) ]   <- "Teaching Faculty"
title[ grepl( "Professor of Practice", d$Job.Description ) ]  <- "Teaching Faculty"

d$title <- factor( title, 
                   levels=c("Full Professor","Associate Professor",
                            "Assistant Professor","Teaching Faculty",
                            "Researcher" ) )

Step 5: Convert Salary to Numeric

Note the format of Salaries in the database. Since it has a dollar sign and comma it is understood to be a text field. As a result, we cannot compute basic statistics like the median salary, and we also cannot recast it easily.

head( d$Salary )
## [1] "$111,133.00" "$46,275.00"  "$37,717.00"  "$53,710.00"  "$91,000.00" 
## [6] "$107,160.00"
head( d$Salary ) %>% as.numeric()
## [1] NA NA NA NA NA NA

Write a function to remove the dollar sign and comma from the strings and return a numeric salary vector. Use it to create a new variable called “salary” (no uppercase S):

d$salary <- convert_currency( d$Salary )

Step 6: Convert All Salaries to Full-Time

For the purposes of comparing apples to apples want FTE salaries, or what the salary each person would earn if they are working full-time (FTE=100).

For example, if someone is working half-time (FTE=50) and is paid $40,000 a year their full-time salary would be $80,000:

40000 / (50/100)
## [1] 80000

Normalize the new salary variable so that it represents everyone’s FTE salary:

salary <- d$salary / (d$FTE / 100)

Note that the format of FTE varies by year. In the 2020 data it ranges from 1 to 100. Other years it ranges from 0 to 1.

To make your function robust include some conditionally:

if( max(d$FTE) == 100 )
{  salary <- d$salary / (d$FTE/100) }

if( max(d$FTE) == 1 )
{ salary <- d$salary / d$FTE }

Convert this step into a function called get_fte().

Step 7: Select Sample

Many university units are administrative and not academic, so we need to select a set of academic units for the report. A list is provided for you below.

Also drop employees that don’t fit into the defined title categories:

academic.units <- 
c("CISA-Intrdisp Hum & Comm", "CISA-Science & Mathmatics", 
"College of Health Solutions MS", "College of Health Solutions NT", 
"College of Health Solutions SH", "College Of Law", "English", "Hugh Downs School Of Comm", 
"Humanities Arts & Cultural", "Journalism & Mass Comm", "Ldrshp and Integrative Studies", 
"Math & Natural Sciences Div", "MDT Music", "Physics Department", 
"Psychology", "Sch Biological & Hlth Sys Engr", "Sch Compt Infor & Dec Sys Engr", 
"Sch Elect Comptr & Energy Engr", "Sch Engr Matter Trnsprt Energy", 
"Sch Future of Innov in Society", "Sch Sustain Engr & Built Envrn", 
"School Of Art", "School of Criminology & Crim J", "School Of Earth & Space Explor", 
"School of Geog Sci & Urban Pln", "School of Math & Stat Sciences", 
"School of Molecular Sciences", "School of Politics & Global St", 
"School Of Public Affairs", "School of Social Transform", "School Of Social Work", 
"SHPRS History Faculty", "Social & Behavioral Sciences", "Sols Administration & Faculty", 
"SOS Faculty & Researchers", "The Design School", "The Sanford School", 
"WPC Accountancy", "WPC Economics", "WPC Information Systems", 
"WPC Management", "WPC Supply Chain Management")

d <- 
  d %>% 
  filter( title != "" & ! is.na(title) ) %>% 
  filter( Department.Description %in% academic.units ) %>% 
  arrange( Department.Description, title )

nrow( d )
## [1] 2459
head( d ) %>% pander()
Table continues below
first.name Calendar.Year Full.Name Job.Description
Barry 2020 Maid, Barry Professor
Brooks 2020 Simpson, Brooks Professor
Eva 2020 Brumberger, Eva Professor
Ian 2020 Moulton, Ian Professor
Jewell 2020 Rhodes, Jewell Professor
Claire 2020 Lauer, Claire Assoc Professor
Table continues below
Department.Description Salary FTE gender proportion_female
CISA-Intrdisp Hum & Comm $54,050.00 50 male 0.0045
CISA-Intrdisp Hum & Comm $145,610.00 100 male 0.0647
CISA-Intrdisp Hum & Comm $106,350.00 100 female 0.9963
CISA-Intrdisp Hum & Comm $100,000.00 100 male 0.0038
CISA-Intrdisp Hum & Comm $297,000.00 100 female 0.8463
CISA-Intrdisp Hum & Comm $90,150.00 100 female 0.9939
title salary
Full Professor 54050
Full Professor 145610
Full Professor 106350
Full Professor 1e+05
Full Professor 297000
Associate Professor 90150

Create a function called get_study_sample() that takes the full salary dataset and returns a subset of employees that belong to the academic units listed above and belong to one of the five title categories we created.

Step 8: Summarize Salaries by Rank and Gender

Create a table of salary iq-range (25th quantile to 75th quantile) that is broken out by the rank of professors (title) and their gender:

The p variable represents the proportion of total employees within each group.

Turn this into a create_salary_table() function.

t.salary <- 
  d %>% 
  filter( ! is.na( title ) & title != "" ) %>% 
  group_by( title, gender ) %>% 
  summarize( q25=quantile(salary,0.25),
             q50=quantile(salary,0.50),
             q75=quantile(salary,0.75),
             n=n() ) %>% 
  ungroup() %>% 
  mutate( p= round( n/sum(n), 2) )

pander( t.salary )
title gender q25 q50 q75 n p
Full Professor male 115798 139198 173329 338 0.14
Full Professor female 108500 129300 160255 141 0.06
Full Professor uncoded 127614 147418 185207 56 0.02
Associate Professor male 95000 105800 121300 229 0.09
Associate Professor female 88928 98421 112949 180 0.07
Associate Professor uncoded 101200 111022 121064 52 0.02
Assistant Professor male 82294 94200 101950 147 0.06
Assistant Professor female 81493 87000 94300 141 0.06
Assistant Professor uncoded 86775 96500 100500 66 0.03
Teaching Faculty male 48575 54000 82350 319 0.13
Teaching Faculty female 47852 52844 65000 378 0.15
Teaching Faculty uncoded 48350 55000 80221 57 0.02
Researcher male 50000 55000 70000 169 0.07
Researcher female 50000 53797 65000 114 0.05
Researcher uncoded 46883 51500 60000 72 0.03

Step 9: Graph Results

I have provided you with functions to create graph of salaries of instructors, assistants, associate, and full professors in each unit reporting results by gender.

Note the chunk arguments:

{r, fig.height=7, fig.width=10}
add_position <- function( t, position, y, xmax, scale.f=8 )
{
  
  t.original <- t
  t <- filter( t.original, title==position )
  dot.size <- 2 + scale.f*sum(t$p)
  offset.n <- 1 + sum(t$p)*2
  
  male.median <- NA
  n.male <- NA
  t <- filter( t.original, title==position & gender == "male" )
  if( nrow(t) > 0 )
  { 
    male.median <- t$q50 
    n.male <- t$n
  }

  
  female.median <- NA
  n.female <- NA
  t <- filter( t.original, title==position & gender == "female" )
  if( nrow(t) > 0 )
  { 
    female.median <- t$q50 
    n.female <- t$n
  }

  
  # dumbell plots 
  segments( x0=female.median, x1=male.median, y0=y,
          col=gray(0.3,0.5), lwd=7 )
  points( male.median, y,
          col=adjustcolor( "darkblue", alpha.f = 0.5), 
          pch=19, cex=dot.size  )
  points( female.median, y,
          col=adjustcolor( "firebrick", alpha.f = 0.5), 
          pch=19, cex=dot.size  )
  
  pos.f <- 2
  pos.m <- 4
  if( ! ( is.na(female.median) | is.na(male.median) ) )
  {
    pos.f <- ifelse( female.median > male.median, 4, 2 )
    pos.m <- ifelse( female.median > male.median, 2, 4 )
  }
  
  # add salaries to right and left 
  text( female.median, y, paste0("$",round(female.median/1000,0),"k"),
        col=adjustcolor( "firebrick", alpha.f = 0.7), 
        cex=1.2, pos=pos.f, offset=offset.n )
  text( male.median, y, paste0("$",round(male.median/1000,0),"k"),
        col=adjustcolor( "darkblue", alpha.f = 0.7), 
        cex=1.2, pos=pos.m, offset=offset.n ) 
  
  # add faculty counts
  n.female <- ifelse( is.na(n.female), 0, n.female )
  n.female <- ifelse( nchar(n.female)==1, 
                      paste0( " ", n.female), n.female )
  n.male <- ifelse( is.na(n.male), 0, n.male )
  n.male <- ifelse( nchar(n.male)==1, 
                      paste0( " ", n.male), n.male )
  text( xmax-0.1*xmax, y+0.14, paste0( "f   = ", n.female),
        col="gray50", cex=1.1, pos=4  )
  text( xmax-0.1*xmax, y-0.14, paste0( "m = ", n.male),
        col="gray50", cex=1.1, pos=4  )


  axis( side=2, at=y, labels=position, 
        las=2, tick=F, cex.axis=1.5, col.axis="gray50" )
}


build_graph <- function( t.salary, unit )
{
  unique.titles <- unique( t.salary$title )
  ymax <- length(unique.titles)
  xmax <- round( max(t.salary$q50), -3 ) + 50000
  color.key.pos <- 40000 + ( xmax - 40000 ) / 2
  color.key.inc <- ( xmax - 40000 ) / 10
  
  t.mf <- filter( t.salary, gender %in% c("male","female") )
  N <- sum( t.mf$n )
  
  par( mar=c(6,15,4.1,0) )
  plot.new()
  plot.window( xlim=c(40000-10000,xmax), ylim=c(0,ymax+1) )
  
  abline( v=seq(40000,xmax-40000,20000), lwd=1.5, lty=2, col=gray(0.5,0.5) )
  axis( side=1, 
        at=seq(40000,xmax-40000,20000), 
        labels=paste0("$",seq(40,(xmax-40000)/1000,20),"k"),
        cex.axis=1.1, col.axis="gray40", tick=FALSE )
  
  y <- ymax
  
  if( "Full Professor" %in% unique.titles )
  {
    add_position( t.salary, position="Full Professor", y, xmax )
    y <- y-1
  }
  if( "Associate Professor" %in% unique.titles )
  {
    add_position( t.salary, position="Associate Professor", y, xmax )
    y <- y-1
  }
  if( "Assistant Professor" %in% unique.titles )
  {
    add_position( t.salary, position="Assistant Professor", y, xmax )
    y <- y-1
  }
  if( "Teaching Faculty" %in% unique.titles )
  {
    add_position( t.salary, position="Teaching Faculty", y, xmax )
    y <- y-1
  }
  if( "Researcher" %in% unique.titles )
  {
    add_position( t.salary, position="Researcher", y, xmax )
    y <- y-1
  }

  
  text( color.key.pos + 3*color.key.inc, 0, "MALE", 
        col=adjustcolor( "darkblue", alpha.f = 0.7), cex=1.2 )
  text( color.key.pos + 1.8*color.key.inc, 0, "FEMALE", 
        col="firebrick",  cex=1.2 )
  text( xmax - 0.1*xmax, 0, paste0("N = ",N), col="gray40",  cex=1.2, pos=4 )

  
  title( main="Median Salary by Rank and Gender", cex.main=1.5, col.main="gray30" )
  title( xlab=unit, col.lab="gray50", cex.lab=1.5, line=5 )
  title( xlab="dot size represents proportion of faculty at that rank",
         col.lab="gray50", cex.lab=0.9 )
  
  return(NULL)
}



### TEST: 
#   t.salary is the salary table from the previous step
#   unit is a category from Department.Description
#
#     build_graph( t.salary, unit="Psychology" )
#


d %>%  
  filter( Department.Description == "Psychology" ) %>% 
  create_table( ) %>% 
  build_graph( unit="Psychology" )

NULL

Step 10 - Top Five Salaries

Create function that generates a table of the top 5 salaries and reports the name, gender, position, and salary of each person on the list.

You might find the following formatting function helpful:

dollarize <- function(x)
{ paste0("$", format( round( x, 0 ), big.mark="," ) ) }

dollarize( x=150000 )
## [1] "$150,000"
Full.Name gender Job.Description salary
LePine, Jeffery male Professor $402,257
Panchanathan, Sethuraman uncoded Professor $365,000
Gomez-Mejia, Luis male Regents Professor $361,393
Hero, Rodney male Professor $341,750
Prescott, Edward male Regents Professor $340,159

The utils.R File

Once all of your functions are working properly copy them all into the utils.R script.

This script will be “sourced” to load all of the functions in your report template (see Part III below).






Part II

All Departments in a Loop

Automate the process using a loop to isolate data from each unit, create the two tables and the graph, then add them to the document.

for( i in academic.units )
{
  
  d2 <- filter( d, Department.Description == i )
  # create the salary summary by rank & gender table 
  # create the top 5 salaries table 
  # build the graph 

  # print the tables:  
  # cat( paste('<h3>',"TOP FIVE SALARIES",'</h3>' ) )
  # cat( t.rank %>% knitr::kable(format="html") )   

  # cat( '<br><hr><br>' )
  
}

Some academic units may not exist in every year of the data so add a control structure that checks if the unit is available and skips trying to add it to the report if that department did not exist yet:

for( i in academic.units )
{
  
  d2 <- filter( d, Department.Description == i )
  if( nrow(d2) == 0 ) { next }  
  # skips the rest of the code in the loop 
  # and start over with the next department
  ...
  
}

You need to include the chunk argument results=‘asis’ and in order to return the raw text from inside a loop you need to use cat() instead of print():

{r, fig.height=7, fig.width=10, results="asis"}

Note, the knitr package has a function called kable that will output nice HTML tables.You can add HTML tables to the RMD through the chunk, then render them to produce nicely-formatted results.

cat( t.rank %>% knitr::kable(format="html") ) 

Your functions-demo.rmd File

Name your current file “functions-demo.rmd”.

The rendered HTML file will serve as the documentation of your process.

  • It should load the 2020 data and will also include all of the custom functions you created.
  • Organize your file with sections for each Step above (step 1, step 2, etc).
  • Do NOT hide your code in this file and demo each function with some test data to show they are working.

In the next step you will create a generic report template (salary-report.rmd) which sources the functions from utils.R and has a generic data load step so you can re-use the template with different years of data (see Part III below).






Part III

Big Picture

You are creating a generic report template that will allow you to run a salary report with any year of data.

The salary-report.rmd template will serve the same purpose as the Resume.rmd template on Lab 6:

  • It sources your custom scripts (parsin_functions.R in the resume example)
  • loads the data (positions.csv)
  • then calls the custom functions to add content to each section.

https://github.com/DS4PS/cv/blob/master/resume.Rmd

source('parsing_functions.R')

position_data <- read_csv('positions.csv')


## Education {data-icon=graduation-cap data-concise=true}

'''{r}
position_data %>% print_section('education')
'''


## Selected Writing {data-icon=newspaper}

'''{r}
position_data %>% print_section('writings')
'''

Your template will have a similar structure:

source( 'utils.R' )   # load custom functions 
 
URL <- params$url     # load data 
d <- read.csv( URL )  

... data cleaning steps ... 


# PSYCHOLOGY

'''{r}
d %>%  
  filter( Department.Description == "Psychology" ) %>% 
  create_salary_table(  ) %>% 
  build_graph( unit="Psychology" )
'''
  
## PAY RANGE BY RANK AND GENDER

'''{r}
d %>% 
  filter( Department.Description == "Psychology" ) %>% 
  create_salary_table(  )
'''

## TOP 5 SALARIES 

etc...

Except you will loop through all academic units:

source( 'utils.R' )

URL <- params$url
d <- read.csv( URL )

... data cleaning steps ...



for( i in academic.units )
{
  
  cat( paste('<h1>', i ,'</h1>' ) )
  
  d %>%  
    filter( Department.Description == i ) %>% 
    create_salary_table() %>% 
    build_graph( unit=i )  

  cat( paste('<h3>', 'PAY RANGE BY RANK AND GENDER' ,'</h3>' ) )

  t.salary <- 
    d %>% 
    filter( Department.Description == i ) %>% 
    create_salary_table()
    
  cat( t.salary %>% knitr::kable(format="html") )

  # etc...

  cat( '<br><hr><br>' )
  
}



Step 1: Create a Generic Salary Report Template

Once you have completed all of these steps you are ready to create your salary report template. It is generic because it will create the same report using different years of data.

Create an RMD template called salary-report.rmd.

Copy all of your new functions into a utils.R file (in R Studio you can use the top menu bar):

select File >> New File >> R Script >> save as utils.R

In the chunk where you load packages add a command to source utils.R to load your custom functions.

library( dplyr )
library... load the rest 

source( 'utils.R' )

Make the data load step generic so you can change the input data at the rmarkdown::render stage (see Step 3 for more details):

Add params to the YAML header:

---
title: 'ASU Salary Report'
output:
  html_document:
    theme: readable
    highlight: zenburn
    toc: true
params:
  url:
    value: x   
---

And change the data load step to:

URL <- params$url
d <- read.csv( URL )

Include each step needed to clean, augment, and analyze the data. Include a loop at the end that generates a report section for each academic unit.

You will build a report using the render function in the rmarkdown package (this is what is called when you “knit” your RMD doc in R Studio):

rmarkdown::render( input='salary-report.rmd', 
                   output_file = "ASU-2020-Salary-Report.HTML",
                   params = # 2020 data url )

Step 2: Customize Your CSS

Customize your salary-report.rmd by adding a CSS section at the end. Change the color of your headers and add some spacing to the tables.

# pretty tables 

td {
    padding: 3px 15px 3px 15px;
    text-align: center !important;
}

th {
    padding: 3px 15px 3px 15px;
    text-align: center !important;
    font-weight: bold;
    color: SlateGray !important;
}

Step 3: Create a Batch Processing Script

We are going to batch process multiple years of reports using functionality in the rmarkdown package.

We will knit reports using the render() function instead of the knit button in R Studio because it allows us to pass parameters to an RMD template the same way we pass arguments to a function. Specifically, we will pass new

BATCH PROCESS SCRIPT:

Create a new R script called ““batch.R”.

This script will render a new report using salary-report.rmd, one for each year. The batch.R file calls the RMD template file, and the RMD template file in-turn sources the custom functions and loads the data.

So your files are chained together as follows:

batch.R 
├── render( url.2020 )
│   ├── salary-template.rmd
│       ├── source( 'utils.R' )
│       ├── read.csv( params$url ) # 2020
├── render( url.2019 )
│   ├── salary-template.rmd
│       ├── source( 'utils.R' )
│       ├── read.csv( params$url ) # 2019
├── render( url.2018 )
│   ├── salary-template.rmd
│       ├── source( 'utils.R' )
│       ├── read.csv( params$url ) # 2018

Note that the same salary-template.rmd and utils.R will be re-used for each report. The only thing that is changing is the data load step.

We can pass url.year to the RMD document THROUGH the render() function, which then changes which year of data is loaded at the read.csv() step in the document.

This means we can reuse the report template over and over, and we have a convenient way to send it the proper data to use.

CREATE A GENERIC DATA LOAD STEP:

We want to change the data load step from a specific year of data:

URL <- 'https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/export?gid=1335284952&format=csv'
d <- read.csv( URL )

To a generic URL placeholder that changes each time we create a new report.

URL <- params$url
d <- read.csv( URL )

To make it possible to send the correct URL to the RMD template at the render stage we need to add a new params field in your YAML header that looks like this:

---
title: 'ASU Salary Report'
output:
  html_document:
    theme: readable
    highlight: zenburn
    toc: true
params:
  url:
    value: x   
---

PASSING NEW DATA TO THE REPORT TEMPLATE:

The YAML fields in the RMD doc are like arguments in a function.

The YAML header provides the defaults, but they can be overwritten using the rmarkdown::render() function. We call this inside the batch.R file.

#####  BATCH.R FILE      


## 2020 REPORT
url.2020 <- "https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/export?gid=1335284952&format=csv"
rmarkdown::render( input='salary-report.rmd', 
                   output_file = "ASU-2020-Salary-Report.HTML",
                   params = list( url = url.2020 ) )

## 2019 REPORT 
url.2019 <- "https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/export?gid=1948400967&format=csv"
rmarkdown::render( input='salary-report.rmd', 
                   output_file = "ASU-2019-Salary-Report.HTML",
                   params = list( url = url.2019 ) )

Here params = list( url = url.2020 ) will populate params$url in the data load chunk of the RMD file:

URL <- params$url
d <- read.csv( URL )

Whichever URL we use in the batch.r file at the render() stage will be the data used to generate the report.


GET THE URL FOR EACH YEAR:

Note that so far we have been working with the 2020 salary data that was loaded directly in the RMD doc:

URL <- 'https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/export?gid=1335284952&format=csv'
d <- read.csv( URL )

The State Press google spreadsheet has multiple years of data organized by tabs. Each tab has a unique URL:

ASU Salaries Spreadsheet

# https://docs.google.com/spreadsheets/d/  <KEY>  /export?gid=  <GID>  &format=csv
# where <KEY> and <GID> can be obtained from the default spreadsheet URL

# Note that the default URL is in EDIT mode, not EXPORT
# https://docs.google.com/spreadsheets/d/<KEY>/edit#gid=<GID>

# IF YOU NEED A LITTLE HELP CREATING THE EXPORT MODE: 

KEY <- "1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E"   # same for all
GID.2020 <- "1335284952"
url.2020 <- paste0( "https://docs.google.com/spreadsheets/d/", KEY, "/export?gid=", GID.2020, "&format=csv" )


# GET THE GOOGLE ID <GID> FOR EACH SHEET
# 2019 sheet:  https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/edit#gid=1948400967
# 2018 sheet:  https://docs.google.com/spreadsheets/d/1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E/edit#gid=169937930

# GID.2019 <- "1948400967"
# url.2019 <- paste0( "https://docs.google.com/spreadsheets/d/", KEY, "/export?gid=", GID.2019, "&format=csv" )
#
# GID.2018 <- "169937930"
# url.2018 <- paste0( "https://docs.google.com/spreadsheets/d/", KEY, "/export?gid=", GID.2018, "&format=csv" )

# etc

Or you can generalize the process:

build_url <- function( GID )
{
  KEY <- "1RoiO9bfpbXowprWdZrgtYXG9_WuK3NFemwlvDGdym7E"
  url <- paste0( "https://docs.google.com/spreadsheets/d/", KEY, "/export?gid=", GID, "&format=csv" )
  return( url )
}

url.2020 <- build_url( GID="1335284952" )



THE BATCH.R FILE:

  • Find the proper URLs for years 2016-2020 (same keys, unique Google IDs) and add them to the file.
  • Use the render function to create a separate report for each year.
  • Make sure to change the output filename and the input URL for each year.

Now run your batch.R script and generate reports for all years.




Helpful Hints

Data Types

Keeping track of data types and your work flow are small details but also one of the most important skills as your projects grow in size and complexity.

A reminder that it is a very good habit to use consistent object names so that you are paying attention to data types.

Some suggestions:

# data frames 
d
df
dat

# subset of a data frame
d2
d.male
dat.top5

# vectors (argument names) 
x, y
v
x.string <- as.character(x)
x.num <- as.numeric(x)

# logical vectors (defining groups)
these
these.female <- gender == "female"

# tables 
t <- table( x, y )
t.salary.by.gender <- d %>% group_by( gender ) %>% summarize( ave=mean(salary) )

# regression models 
m
m1
m2

Once you are working with a larger project you will see the importance of good housekeeping and organizational skills.

Data types are not trivial! Creating a habit of naming objects by data type will force you to be aware of your objects as well as pay attention to proper argument types and return values when creating functions.

Functions

Functions are input-output machines. They take inputs and transform them into something else.

Notes on Functions

Recall that a function is just a recipe. For the recipe to work properly all of the ingredients need to be provided to the function as arguments.

Pay attention to three main types of functions in this project - those that refine vectors, those that augment data frames, and those that transform a data frame into a table.

# VECTORS
refine_vector <- function(x)
{
  x <- do_something(x)
  return(x)
}

# USE:
# d$x <- refine_vector( d$x )



# DATA FRAMES
augment_df <- function(d)
{
  
  # add variable to d
  x2 <- augment(d$x)
  d$x2 <- x2
  
  # filter rows
  d <- filter( d, y > 10 )
  
  # select columns 
  d <- select( d, x, y, z )
  
  return(d)
  
}

# USE: 
# d <- augment_df( d )



# TABLES
build_table <- function(d)
{
  
  t <- 
    d %>%
    group_by( f1, f2 ) %>% 
    summarize( ave.x=mean(x) )
  
  return(t)
  
}

# USE: 
# t <- build_table( d )

Pay attention to what you are trying to accomplish with the task.

For example, Step 4 asks you to create a function to recode titles to build a new title variable from the current Job.Description variable.

There are different ways we can accomplish this. Here’s an approach that uses the data frame as the input-output object type (adds new variable to the data frame, returns new augmented data frame):

add_titles <- function(d)
{
  # code abstraction 
  title <- some_process( d$Job.Description )
  d$title <- title
  return(d)
}

# USE: 
# d <- add_titles( d )

Alternatively, if we look at the code we can see that the only information we need for the task is the Job.Description variable, so we could structure the function around the vector of job descriptions:

recode_job_description <- function( job.desc )
{
  # code abstraction 
  title <- some_process( job.desc )
  return(title)
}

# USE: 
# d$title <- recode_job_description( d$Job.Description )

Both approaches are reasonable in this case. Whichever you choose, though, the very important detail to pay attention to is the journey of your data through the load and wrangling steps as it is refined, augmented, and reshaped to prepare it for whatever analysis is presented in the report.

# DATA FRAME APPROACH 
d <- add_titles( d )

# VECTOR APPROACH 
d$title <- recode_job_description( d$Job.Description )

One of the reasons the first approach is preferable is that functions that use data frames as both the input and the output can be added to data recipes using pipes:

d %>% 
  add_gender() %>% 
  add_titles() %>% 
  fix_salary() 

If we use a vectorized function we can’t use that approach since recode_job_description() will expect a vector as the input information and it will also output a vector as the return object:

# error: 
d %>% 
  add_gender() %>% 
  recode_job_description() %>%     # expecting a vector
  fix_salary()                     # expecting a df 


# without pipes:  
d <- add_gender( d )
d$title <- recode_job_description( d$Job.Description )
d <- fix_salary( d )

Date Joins (Merging dfs)

If it’s been awhile since you have had to conduct a merge.

Data Joins

Full.Name first.name Salary
Bae, Aaron Aaron $52,750.00
Baker, Aaron Aaron $107,160.00
Ball, Aaron Aaron $127,690.00

Why do we use unique names and always check data frame dimensions before and after merges?

Note that you will query only a list of unique first names:

unique.names <- unique( d$first.name )

What happens if we send name duplicates to the gender package? It will send back one match per name and it won’t check to make sure there are no duplicates.

g <- gender( df.aaron$first.name ) 
g %>% pander()
name proportion_male proportion_female gender year_min year_max
Aaron 0.9918 0.0082 male 1932 2012
Aaron 0.9918 0.0082 male 1932 2012
Aaron 0.9918 0.0082 male 1932 2012

Let’s see what happens if we merge these two data frames. I’ll number the observations in the gender table so it’s easier to see what happens:

g <- 
  g %>%
  select( name, gender ) %>% 
  mutate( gender = paste0( gender, 1:3 ) ) 
  

merge( df.aaron, g, by.x="first.name", by.y="name" ) %>% pander()
first.name Full.Name Salary gender
Aaron Bae, Aaron $52,750.00 male1
Aaron Bae, Aaron $52,750.00 male2
Aaron Bae, Aaron $52,750.00 male3
Aaron Baker, Aaron $107,160.00 male1
Aaron Baker, Aaron $107,160.00 male2
Aaron Baker, Aaron $107,160.00 male3
Aaron Ball, Aaron $127,690.00 male1
Aaron Ball, Aaron $127,690.00 male2
Aaron Ball, Aaron $127,690.00 male3

We started with 3 Aarons in df.aaron and 3 Aarons in the gender data frame g.

Starting with Aaron Bae, the merge() function looks to g to find which columns to append to Bae’s data. Since we are merging on first names only, though, we can’t differentiate between any of the Aarons and as a result merge will append all Aarons from g to each Aaron in df.aaron.

Since we have 3 Aarons in this dataset that means we would have 3 separate Aaron cases in the gender data frame if we do not send a list of unique names only. That means we append 3 observations per Aaron for a total of 3x3 = 9 rows in the final dataset.

In the full dataset we have 36 Aarons, so this mistake would result in 36x36 = 1,296 rows of Aarons. And Aaron is not even the most common name. There are 191 Michaels, so this error would generate 36,481 rows of Michaels in the final dataset!

Pay attention to your data joins. It’s one of the cases where arguments and duplicates matter a great deal and the merge will likely work with the wrong arguments or if duplicates are present but will corrupt your dataset.

Sorting Salaries

Will the Salary variable sort correctly? What’s happening here?

x <-
c("$35,090.00", "$71,400.00", "$36,000.00", "$64,000.00", "$20,800.00", 
"$107,195.00", "$147,225.00", "$98,426.00", "$89,406.00", "$95,095.00" )

sort( x, decreasing=TRUE )
##  [1] "$98,426.00"  "$95,095.00"  "$89,406.00"  "$71,400.00"  "$64,000.00" 
##  [6] "$36,000.00"  "$35,090.00"  "$20,800.00"  "$147,225.00" "$107,195.00"

Recall the difference between sorting numbers (arrange by magnitude) and alphabetizing strings. Since Salary contains dollar signs and commas it will be a string. You can sort it, but sorting strings uses alphabetization rules, not magnitude.

Sort the numeric version of salary, then format (dollarize) to make it look nice in a table.




Submission Instructions

Deliverables

You have the following files:

  • utils.R - contains all of your helper functions
  • function-demo.rmd, function-demo.html - show each helper function in action
  • salary-report.rmd - report template
  • batch.R - generates reports for all years
  • five rendered HTML reports:
    • “ASU-2020-Salary-Report.HTML”
    • “ASU-2019-Salary-Report.HTML”
    • “ASU-2018-Salary-Report.HTML”
    • “ASU-2017-Salary-Report.HTML”
    • “ASU-2016-Salary-Report.HTML”

The relationship between files:

function-demo.rmd 
├── output: function-demo.html

batch.R 
├── render( salary-template.rmd ) # 2020 data
│       ├── source( 'utils.R' )
│       ├── output: ASU-2020-Salary-Report.HTML

├── render( salary-template.rmd ) # 2019 data
│       ├── source( 'utils.R' )
│       ├── output: ASU-2019-Salary-Report.HTML

├── render( salary-template.rmd ) # 2018 data
│       ├── source( 'utils.R' )
│       ├── output: ASU-2018-Salary-Report.HTML

In the function-demo.rmd file include all of your code and demo each function from Steps 1-10 above so I can see they are working properly.

The salary-report.rmd file, on the other hand, will hide the code so that it generates a clean report. Make sure to suppress warnings and messages as well. The knitr options argument is helpful:

knitr::opts_chunk$set( echo=F, message=F, warning=F )

Grade Break-Down

This assignment is worth 15 points and is broken into 3 main parts with points assigned as follows:

Part I: Working Functions (5 Points)

I will source the utils.R file and test your functions.

Part II: Working Report (5 Points)

Does your function-demo.rmd file knit and does it produce proper report sections for the 2020 data (the two tables and one graph)?

Note that this is your documentation file, so include all of the data wrangling steps and show all of your code.

Part III: Batch Process (5 Points)

Does salary-report.rmd produce a report?

Can I run your batch.R script and generate fresh reports for all 5 years without getting errors?

Partial Credit

Start from the top and work your way through the assignment. Complete what you can. If you can’t get a step to work then submit your files and explain where they get stuck. I can at least give partial credit for a section if I can see what you are doing.


Submission

Zip the nine files above into a project directory and upload to canvas.

Name your files: CPP-527-FINAL-LastName.zip






Demo Report Sections

Your final reports should look something like this:

CISA-Intrdisp Hum & Comm

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Rhodes, Jewell female Professor $297,000
Simpson, Brooks male Professor $145,610
Brumberger, Eva female Professor $106,350
Moulton, Ian male Professor $100,000
Nystrom, Eric male Assoc Professor $ 94,612

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $ 77,025 $100,000 $122,805 3 0.07
Full Professor female $154,012 $201,675 $249,338 2 0.04
Associate Professor male $ 94,612 $ 94,612 $ 94,612 1 0.02
Associate Professor female $ 88,762 $ 89,225 $ 89,688 2 0.04
Assistant Professor male $ 73,512 $ 74,025 $ 74,512 3 0.07
Assistant Professor female $ 72,100 $ 72,200 $ 74,375 3 0.07
Assistant Professor uncoded $ 65,000 $ 65,000 $ 65,000 1 0.02
Teaching Faculty male $ 24,389 $ 46,400 $ 48,897 9 0.20
Teaching Faculty female $ 46,512 $ 48,590 $ 51,706 20 0.44
Teaching Faculty uncoded $ 24,490 $ 24,490 $ 24,490 1 0.02



CISA-Science & Mathmatics

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Sagers, Cynthia female Professor $123,750
Zandieh, Michelle female Professor $113,288
Shovkovy, Igor male Professor $107,675
Kang, Yun female Professor $103,330
Sukharev, Maxim male Professor $103,096

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $104,241 $105,386 $106,530 2 0.05
Full Professor female $108,309 $113,288 $118,519 3 0.08
Associate Professor male $ 89,752 $ 95,208 $ 95,847 3 0.08
Associate Professor female $ 93,698 $ 94,882 $ 96,066 2 0.05
Associate Professor uncoded $ 90,333 $ 90,333 $ 90,333 1 0.03
Assistant Professor male $ 82,780 $ 83,628 $ 84,814 3 0.08
Assistant Professor female $ 81,357 $ 82,714 $ 84,070 2 0.05
Assistant Professor uncoded $ 84,536 $ 85,024 $ 85,512 2 0.05
Teaching Faculty male $ 48,925 $ 50,000 $ 58,082 9 0.24
Teaching Faculty female $ 48,686 $ 48,925 $ 56,949 7 0.18
Teaching Faculty uncoded $ 48,106 $ 48,350 $ 49,275 3 0.08
Researcher female $ 58,000 $ 58,000 $ 58,000 1 0.03



College of Health Solutions MS

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Gaesser, Glenn male Professor $162,943
Adams, Marc male Assoc Professor $120,280
Siegler, Jason male Assoc Professor $115,000
Huberty, Jennifer female Assoc Professor $103,650
Der Ananian, Cheryl female Assoc Professor $ 93,600

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $162,943 $162,943 $162,943 1 0.03
Associate Professor male $ 97,398 $115,000 $117,640 3 0.09
Associate Professor female $ 92,248 $ 93,299 $ 96,112 4 0.12
Assistant Professor male $ 59,438 $ 69,625 $ 79,812 2 0.06
Assistant Professor female $ 88,000 $ 88,000 $ 88,000 1 0.03
Teaching Faculty male $ 53,062 $ 59,000 $ 63,550 7 0.22
Teaching Faculty female $ 54,500 $ 55,215 $ 57,482 11 0.34
Researcher female $ 48,789 $ 50,000 $ 51,352 3 0.09



College of Health Solutions NT

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Ohri-Vachaspati, Punam female Professor $165,543
Wang, Shu male Professor $160,000
Banks, Dorothy female Professor $140,000
Bruening, Meredith female Assoc Professor $120,280
Vega-Lopez, Sonia female Assoc Professor $113,460

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $160,000 $160,000 $160,000 1 0.03
Full Professor female $146,386 $152,772 $159,157 2 0.06
Associate Professor female $105,589 $106,665 $113,460 5 0.16
Assistant Professor female $ 89,000 $ 89,000 $ 89,000 1 0.03
Assistant Professor uncoded $ 94,700 $ 94,700 $ 94,700 1 0.03
Teaching Faculty female $ 53,625 $ 56,600 $ 63,725 17 0.55
Researcher male $ 48,113 $ 48,742 $ 49,371 2 0.06
Researcher female $ 63,650 $ 66,100 $ 68,550 2 0.06



College of Health Solutions SH

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Scherer, Nancy female Professor $156,634
Gray, Shelley female Professor $147,400
Berisha, Visar uncoded Assoc Professor $118,400
Schatzki, MariaRita uncoded Clinical Assoc Professor (FSC) $106,308
Reddy, Corianne female Assoc Professor $102,000

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor female $149,708 $152,017 $154,326 2 0.06
Associate Professor male $101,397 $101,397 $101,397 1 0.03
Associate Professor female $100,354 $101,709 $101,854 3 0.10
Associate Professor uncoded $118,400 $118,400 $118,400 1 0.03
Assistant Professor male $ 98,000 $ 98,000 $ 98,000 1 0.03
Assistant Professor female $ 98,050 $ 98,200 $ 98,350 2 0.06
Teaching Faculty female $ 77,500 $ 80,000 $ 84,780 13 0.42
Teaching Faculty uncoded $106,308 $106,308 $106,308 1 0.03
Researcher male $ 29,120 $ 37,440 $ 66,192 3 0.10
Researcher female $ 26,239 $ 27,642 $ 37,438 4 0.13



College Of Law

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Bodansky, Daniel male Regents Professor $274,000
Banks, Angela female Professor $255,250
Roberts, Lawrence male Professor of Practice $250,000
Selmi, Michael male Professor $225,000
Williamson, John male Professor of Practice $220,000

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $165,294 $169,050 $170,696 14 0.30
Full Professor female $160,841 $162,996 $174,498 6 0.13
Associate Professor male $135,750 $138,000 $151,869 6 0.13
Associate Professor female $149,830 $156,460 $156,476 3 0.06
Associate Professor uncoded $ 93,876 $ 93,876 $ 93,876 1 0.02
Teaching Faculty male $ 60,000 $ 68,000 $192,600 9 0.19
Teaching Faculty female $ 67,250 $ 68,000 $ 87,500 6 0.13
Teaching Faculty uncoded $ 75,000 $ 75,000 $ 75,000 1 0.02
Researcher male $ 45,000 $ 45,000 $ 45,000 1 0.02



English

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Bate, Andrew male Professor $250,000
Diaz, Natalie female Assoc Professor $210,200
Justice, George male Professor $186,000
Bjork, Robert male Professor $163,750
Looser, Devoney female Professor $160,387

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $105,893 $116,259 $138,985 19 0.13
Full Professor female $111,050 $122,425 $130,020 13 0.09
Associate Professor male $ 92,994 $ 93,820 $ 95,142 11 0.07
Associate Professor female $ 88,408 $ 95,862 $ 97,316 9 0.06
Assistant Professor male $ 78,900 $ 79,500 $ 80,000 5 0.03
Assistant Professor female $ 80,046 $ 81,246 $ 82,131 8 0.05
Assistant Professor uncoded $102,000 $102,000 $102,000 1 0.01
Teaching Faculty male $ 49,000 $ 52,100 $ 52,600 32 0.21
Teaching Faculty female $ 49,000 $ 52,600 $ 52,600 46 0.31
Teaching Faculty uncoded $ 49,000 $ 51,600 $ 52,600 5 0.03



Hugh Downs School Of Comm

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Lederman, Linda female Professor $220,000
Tracy, Sarah female Professor $135,670
Corman, Steven male Professor $130,500
Alberts, Janet female President’s Professor $129,300
Roberto, Anthony male Professor $119,450

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $115,870 $119,450 $124,975 3 0.06
Full Professor female $111,118 $120,955 $134,078 6 0.11
Associate Professor male $ 95,050 $ 97,700 $ 98,185 3 0.06
Associate Professor female $100,600 $100,600 $100,600 1 0.02
Associate Professor uncoded $ 89,907 $ 89,978 $ 90,048 2 0.04
Assistant Professor male $ 74,500 $ 74,500 $ 74,500 1 0.02
Assistant Professor female $ 75,350 $ 76,700 $ 78,350 3 0.06
Assistant Professor uncoded $ 77,300 $ 77,300 $ 77,300 1 0.02
Teaching Faculty male $ 45,000 $ 47,050 $ 47,190 13 0.24
Teaching Faculty female $ 37,730 $ 45,600 $ 47,190 20 0.37
Teaching Faculty uncoded $ 46,200 $ 46,200 $ 46,200 1 0.02



Humanities Arts & Cultural

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Pagan, Eduardo male Assoc Professor $114,900
Hanlon, Christopher male Professor $105,275
Guzzetti, Barbara female Professor $101,607
Kim, Marianne female Professor $100,276
Fahs, Breanne female Professor $ 99,962

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $65,161 $83,974 $100,417 4 0.08
Full Professor female $97,540 $99,556 $100,198 6 0.12
Associate Professor male $88,016 $88,335 $ 91,288 8 0.15
Associate Professor female $85,325 $86,620 $ 88,704 10 0.19
Assistant Professor male $75,830 $75,830 $ 75,830 1 0.02
Assistant Professor female $75,750 $75,750 $ 75,750 1 0.02
Teaching Faculty male $48,300 $48,470 $ 58,200 5 0.10
Teaching Faculty female $46,150 $47,750 $ 48,685 15 0.29
Teaching Faculty uncoded $48,338 $50,546 $ 52,753 2 0.04



Journalism & Mass Comm

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Misner, John male Professor of Practice (FSC) $196,223
Beelman, Maud female Professor of Practice (FSC) $185,000
Cohen, Sarah female Professor $157,579
Wallace, Julia female Professor of Practice $156,259
Downie, Leonard male Professor of Practice $155,448

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $ 65,760 $ 68,050 $ 79,391 3 0.07
Full Professor female $157,579 $157,579 $157,579 1 0.02
Associate Professor male $ 70,154 $ 70,963 $ 75,479 3 0.07
Associate Professor female $ 74,789 $ 80,611 $ 88,440 6 0.14
Associate Professor uncoded $ 89,635 $ 89,635 $ 89,635 1 0.02
Assistant Professor male $ 69,216 $ 70,122 $ 71,027 2 0.05
Assistant Professor female $ 67,591 $ 67,591 $ 67,591 1 0.02
Teaching Faculty male $ 92,362 $105,816 $139,440 12 0.27
Teaching Faculty female $104,105 $115,591 $143,440 15 0.34



Ldrshp and Integrative Studies

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Akpan, Patience female Assoc Professor $89,000
Bates, Denise female Asst Professor $73,429
Giron, Angela female Clinical Asst Professor (FSC) $71,722
Castillo, Elizabeth female Asst Professor $70,749
Trinh, Mai female Asst Professor $70,740

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Associate Professor male $43,985 $43,985 $43,985 1 0.03
Associate Professor female $89,000 $89,000 $89,000 1 0.03
Assistant Professor male $70,653 $70,653 $70,653 1 0.03
Assistant Professor female $70,744 $70,749 $72,089 3 0.08
Teaching Faculty male $48,524 $49,623 $53,370 16 0.42
Teaching Faculty female $48,839 $50,796 $54,494 14 0.37
Teaching Faculty uncoded $47,080 $47,159 $47,238 2 0.05



Math & Natural Sciences Div

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Dietrich, Suzanne female Professor $127,995
Camacho, Erika female Professor $121,440
Kanthaswamy, Sreetharan uncoded Professor $117,645
Sullivan, Brian male Professor $111,420
Marshall, Pamela female Professor $107,234

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $ 91,243 $104,397 $105,975 5 0.08
Full Professor female $114,337 $121,440 $124,718 3 0.05
Full Professor uncoded $100,774 $106,398 $112,022 2 0.03
Associate Professor male $ 89,577 $ 90,402 $ 91,915 5 0.08
Associate Professor female $ 95,773 $ 97,358 $ 98,546 4 0.06
Associate Professor uncoded $100,166 $100,166 $100,166 1 0.02
Assistant Professor male $ 86,750 $ 87,000 $ 88,077 4 0.06
Assistant Professor female $ 88,000 $ 90,000 $ 91,599 5 0.08
Assistant Professor uncoded $ 89,062 $ 91,125 $ 93,188 2 0.03
Teaching Faculty male $ 45,000 $ 47,275 $ 55,250 12 0.19
Teaching Faculty female $ 45,000 $ 47,450 $ 53,322 16 0.26
Teaching Faculty uncoded $ 57,684 $ 57,684 $ 57,684 1 0.02
Researcher male $ 62,600 $ 62,600 $ 62,600 1 0.02
Researcher uncoded $ 60,000 $ 60,000 $ 60,000 1 0.02



MDT Music

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Marshall, Kimberly female Professor $121,288
Roumain, Daniel male Professor of Practice, MY $121,185
Spring, Robert male Professor $115,305
Meyer, Jeffery male Assoc Professor $112,325
DeMaris, Brian male Assoc Professor $109,184

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $87,016 $92,271 $ 94,935 13 0.20
Full Professor female $87,690 $92,661 $ 94,540 7 0.11
Full Professor uncoded $91,886 $91,886 $ 91,886 1 0.02
Associate Professor male $84,210 $91,956 $102,092 7 0.11
Associate Professor female $73,313 $76,250 $ 77,679 6 0.09
Assistant Professor male $63,254 $65,072 $ 72,190 11 0.17
Assistant Professor female $63,145 $64,666 $ 70,575 6 0.09
Teaching Faculty male $33,476 $46,718 $ 71,092 10 0.15
Teaching Faculty female $44,742 $57,362 $ 69,239 4 0.06



Physics Department

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Ritchie, Barry male Professor $233,201
Nemanich, Robert male Regents Professor $210,580
Smith, David male Regents Professor $184,222
Spence, John male Regents Professor $184,200
Liu, Jingyue uncoded Professor $180,825

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $116,544 $134,000 $175,535 18 0.26
Full Professor female $112,269 $112,880 $113,490 2 0.03
Full Professor uncoded $104,376 $118,932 $149,878 3 0.04
Associate Professor male $108,413 $111,662 $114,505 8 0.11
Associate Professor female $105,700 $105,700 $105,700 1 0.01
Assistant Professor male $ 92,000 $ 92,500 $ 92,800 5 0.07
Assistant Professor female $ 93,500 $ 93,500 $ 93,650 3 0.04
Teaching Faculty male $ 28,000 $ 28,000 $ 28,000 1 0.01
Teaching Faculty female $ 58,200 $ 58,200 $ 58,200 1 0.01
Researcher male $ 49,607 $ 51,670 $ 66,650 14 0.20
Researcher female $ 47,957 $ 50,450 $ 51,563 6 0.09
Researcher uncoded $ 47,476 $ 49,700 $ 51,498 8 0.11



Psychology

TOP FIVE SALARIES

Full.Name gender Job.Description salary
McNamara, Danielle female Professor $227,000
Chassin, Laurie female Regents Professor $226,418
Mackinnon, David male Professor $177,750
Kenrick, Douglas male President’s Professor $176,765
Goldinger, Stephen male Professor $175,575

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $121,920 $133,778 $164,629 14 0.18
Full Professor female $122,167 $151,298 $184,948 8 0.10
Full Professor uncoded $116,114 $118,250 $120,386 2 0.03
Associate Professor male $ 98,000 $106,250 $112,619 9 0.12
Associate Professor female $108,367 $113,215 $121,520 5 0.06
Associate Professor uncoded $111,780 $111,780 $111,780 1 0.01
Assistant Professor female $ 92,000 $ 92,750 $ 93,875 6 0.08
Assistant Professor uncoded $ 92,000 $ 92,000 $ 92,000 1 0.01
Teaching Faculty male $ 80,702 $ 85,175 $ 88,888 4 0.05
Teaching Faculty female $ 39,131 $ 52,000 $ 61,322 4 0.05
Teaching Faculty uncoded $ 35,971 $ 43,648 $ 51,324 2 0.03
Researcher male $ 56,352 $ 60,000 $ 78,998 3 0.04
Researcher female $ 50,004 $ 50,760 $ 62,000 17 0.22
Researcher uncoded $ 90,534 $108,289 $126,044 2 0.03



Sch Biological & Hlth Sys Engr

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Kleim, Jeffrey male Assoc Professor $159,301
Tyler, William male Assoc Professor $148,600
Lockhart, Thurmon male Professor $135,000
Stabenfeldt, Sarah female Assoc Professor $125,833
Sadleir, Rosalind female Assoc Professor $124,428

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $135,000 $135,000 $135,000 1 0.02
Associate Professor male $107,706 $117,972 $121,982 11 0.26
Associate Professor female $124,058 $124,428 $125,130 3 0.07
Associate Professor uncoded $111,557 $111,557 $111,557 1 0.02
Assistant Professor male $ 97,250 $ 98,000 $103,692 4 0.10
Assistant Professor female $100,365 $102,126 $103,617 4 0.10
Assistant Professor uncoded $ 97,000 $ 98,000 $ 98,000 3 0.07
Teaching Faculty male $ 72,878 $ 74,357 $ 75,836 2 0.05
Teaching Faculty female $ 73,185 $ 73,185 $ 73,185 1 0.02
Researcher male $ 49,885 $ 50,000 $ 52,500 5 0.12
Researcher female $ 54,500 $ 55,000 $ 68,700 3 0.07
Researcher uncoded $ 50,003 $ 50,502 $ 51,770 4 0.10



Sch Compt Infor & Dec Sys Engr

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Panchanathan, Sethuraman uncoded Professor $365,000
VanLehn, Kurt male Professor $240,565
Kambhampati, Subbarao uncoded Professor $224,719
Liu, Huan male Professor $211,536
Mirchandani, Pitu uncoded Professor $206,710

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $146,668 $176,501 $195,980 10 0.11
Full Professor female $144,750 $147,500 $150,250 2 0.02
Full Professor uncoded $156,918 $177,231 $200,075 11 0.12
Associate Professor male $108,716 $126,500 $130,815 8 0.09
Associate Professor female $104,035 $111,735 $114,165 3 0.03
Associate Professor uncoded $106,760 $115,127 $121,603 6 0.07
Assistant Professor male $101,450 $104,400 $109,750 11 0.12
Assistant Professor female $102,750 $105,500 $107,750 3 0.03
Assistant Professor uncoded $106,875 $112,500 $113,625 6 0.07
Teaching Faculty male $ 79,552 $ 85,000 $ 89,446 9 0.10
Teaching Faculty female $ 54,375 $ 82,500 $ 90,699 7 0.08
Teaching Faculty uncoded $ 94,966 $ 98,506 $ 99,805 4 0.05
Researcher male $ 80,107 $ 97,587 $121,669 6 0.07
Researcher female $ 70,886 $ 71,771 $ 72,656 2 0.02



Sch Elect Comptr & Energy Engr

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Vittal, Vijay male Regents Professor $298,000
Lai, Ying-Cheng uncoded Professor $270,200
Kiaei, Sayfe uncoded Professor $264,880
Meldrum, Deirdre female Professor $235,250
Balanis, Constantine male Regents Professor $221,879

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $125,870 $160,888 $172,700 17 0.17
Full Professor female $154,620 $160,298 $177,500 8 0.08
Full Professor uncoded $143,667 $171,328 $202,000 10 0.10
Associate Professor male $116,660 $119,340 $126,580 9 0.09
Associate Professor female $116,378 $118,065 $120,885 4 0.04
Associate Professor uncoded $107,900 $107,959 $112,570 3 0.03
Assistant Professor male $ 98,000 $103,000 $105,000 11 0.11
Assistant Professor female $108,500 $108,500 $108,500 1 0.01
Assistant Professor uncoded $ 99,375 $102,750 $105,375 6 0.06
Teaching Faculty male $ 75,500 $ 77,000 $ 78,750 3 0.03
Teaching Faculty female $ 80,000 $ 80,000 $ 80,000 1 0.01
Researcher male $ 50,750 $ 65,000 $ 70,000 20 0.20
Researcher uncoded $ 53,500 $ 55,000 $ 62,960 7 0.07



Sch Engr Matter Trnsprt Energy

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Chattopadhyay, Aditi female Regents Professor $292,157
Dahm, Werner male Professor $248,748
Lin, Jerry male Regents Professor $218,200
Jannesari Ladani, Leila female Professor $185,000
Rege, Kaushal male Professor $165,000

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $143,412 $151,324 $160,003 18 0.16
Full Professor female $211,789 $238,578 $265,368 2 0.02
Full Professor uncoded $134,802 $147,042 $156,154 4 0.04
Associate Professor male $111,040 $116,990 $124,088 11 0.10
Associate Professor female $112,709 $116,429 $119,550 5 0.04
Associate Professor uncoded $104,658 $116,033 $121,064 8 0.07
Assistant Professor male $ 97,500 $ 99,500 $100,500 9 0.08
Assistant Professor female $102,190 $103,380 $104,190 3 0.03
Assistant Professor uncoded $ 96,625 $ 98,000 $101,250 10 0.09
Teaching Faculty male $ 22,000 $ 80,000 $ 84,000 9 0.08
Teaching Faculty uncoded $ 74,750 $ 76,000 $ 77,250 2 0.02
Researcher male $ 45,000 $ 48,925 $ 52,500 17 0.15
Researcher female $ 50,172 $ 51,443 $ 55,722 3 0.03
Researcher uncoded $ 35,607 $ 45,000 $ 48,107 12 0.11



Sch Future of Innov in Society

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Cook-Deegan, Robert male Professor $204,480
Barab, Sasha female Professor $199,896
Michael, Katina female Professor $179,725
Martin, Paul male Research Professional FSC $169,538
Mayes, Kristin female Professor of Practice (FSC) $162,742

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $155,287 $155,969 $180,224 3 0.07
Full Professor female $184,768 $189,810 $194,853 2 0.04
Associate Professor male $ 95,728 $102,467 $108,301 3 0.07
Associate Professor female $ 86,142 $ 96,800 $100,920 3 0.07
Associate Professor uncoded $113,874 $113,874 $113,874 1 0.02
Assistant Professor male $ 94,015 $ 94,264 $ 94,512 2 0.04
Assistant Professor female $ 75,655 $ 86,355 $ 92,880 8 0.18
Assistant Professor uncoded $ 92,700 $ 92,700 $ 92,700 1 0.02
Teaching Faculty male $ 52,148 $ 58,878 $ 82,310 4 0.09
Teaching Faculty female $ 71,708 $103,138 $158,386 7 0.16
Researcher male $ 46,150 $ 50,000 $ 94,889 7 0.16
Researcher female $ 49,325 $ 58,242 $ 70,998 4 0.09



Sch Sustain Engr & Built Envrn

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Kavazanjian, Edward male Regents Professor $260,500
Westerhoff, Paul male Regents Professor $255,300
Hjelmstad, Keith male President’s Professor $253,100
Allenby, Braden male President’s Professor $243,400
Lackner, Klaus male Professor $228,900

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $138,620 $195,798 $245,825 12 0.16
Full Professor uncoded $140,527 $144,645 $147,469 4 0.05
Associate Professor male $107,332 $112,300 $125,400 11 0.15
Associate Professor female $108,925 $111,650 $116,075 3 0.04
Associate Professor uncoded $110,375 $111,350 $112,145 4 0.05
Assistant Professor male $ 96,600 $ 99,100 $101,500 5 0.07
Assistant Professor female $ 97,900 $ 97,900 $ 99,350 3 0.04
Assistant Professor uncoded $ 97,000 $ 97,400 $ 99,350 4 0.05
Teaching Faculty male $ 76,425 $ 80,750 $ 87,100 4 0.05
Teaching Faculty female $ 39,500 $ 39,500 $ 39,500 1 0.01
Teaching Faculty uncoded $ 79,400 $ 79,400 $ 79,400 1 0.01
Researcher male $ 41,130 $ 60,000 $ 70,395 10 0.14
Researcher female $ 55,000 $ 66,250 $ 76,534 4 0.05
Researcher uncoded $ 48,750 $ 60,300 $ 63,250 8 0.11



School Of Art

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Klett, Mark male Regents Professor $146,336
Weiser, Kurt male Regents Professor $140,243
Lawson, Shawn male Assoc Professor $118,000
Codell, Julie female Professor $113,462
Neubauer, Mary female President’s Professor $110,523

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $87,681 $90,912 $106,227 9 0.18
Full Professor female $89,168 $91,731 $ 99,997 11 0.22
Associate Professor male $76,732 $77,820 $ 97,910 3 0.06
Associate Professor female $74,898 $81,018 $ 85,000 9 0.18
Assistant Professor male $64,000 $64,000 $ 64,000 1 0.02
Assistant Professor female $64,150 $65,133 $ 66,155 5 0.10
Assistant Professor uncoded $64,500 $64,500 $ 64,500 1 0.02
Teaching Faculty male $46,925 $47,950 $ 48,975 2 0.04
Teaching Faculty female $44,850 $45,900 $ 59,842 10 0.20



School of Criminology & Crim J

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Spohn, Cassia female Regents Professor $226,000
White, Michael male Professor $173,538
Maguire, Edward male Professor $163,500
Hepburn, John male Professor $143,213
Reisig, Michael male Professor $142,300

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $142,985 $153,356 $166,010 4 0.11
Full Professor female $145,251 $172,168 $199,084 2 0.05
Associate Professor male $100,688 $101,938 $103,753 4 0.11
Associate Professor female $100,148 $101,000 $101,250 5 0.13
Associate Professor uncoded $110,000 $110,000 $110,000 1 0.03
Assistant Professor male $ 84,050 $ 84,100 $ 84,150 2 0.05
Assistant Professor female $ 83,750 $ 84,100 $ 84,400 4 0.11
Teaching Faculty male $ 48,000 $ 51,000 $ 58,250 11 0.29
Teaching Faculty female $ 53,000 $ 53,000 $ 54,000 5 0.13



School Of Earth & Space Explor

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Bell, James male Professor $222,400
Christensen, Philip male Regents Professor $216,050
Windhorst, Rogier uncoded Regents Professor $189,950
Anbar, Ariel female President’s Professor $189,800
Timmes, Francis male Professor $188,705

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $136,306 $146,531 $168,300 19 0.19
Full Professor female $189,800 $189,800 $189,800 1 0.01
Full Professor uncoded $155,527 $167,002 $178,476 2 0.02
Associate Professor male $112,612 $113,100 $120,050 3 0.03
Associate Professor female $114,156 $119,050 $121,250 5 0.05
Associate Professor uncoded $127,966 $129,183 $130,400 2 0.02
Assistant Professor male $ 92,000 $ 96,000 $ 98,200 5 0.05
Assistant Professor female $ 92,000 $ 93,500 $ 95,750 4 0.04
Assistant Professor uncoded $ 96,000 $ 96,000 $ 97,000 3 0.03
Teaching Faculty female $ 45,000 $ 45,000 $ 45,000 1 0.01
Researcher male $ 54,096 $ 63,500 $ 73,225 34 0.34
Researcher female $ 56,324 $ 65,000 $ 70,232 15 0.15
Researcher uncoded $ 60,000 $ 60,000 $ 75,196 5 0.05



School of Geog Sci & Urban Pln

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Fotheringham, Stewart male Regents Professor $333,200
Turner, Billie female Regents Professor $221,647
Sailor, David male Professor $141,453
Cerveny, Randall male President’s Professor $132,462
Dorn, Ronald male Professor $124,288

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $115,722 $119,964 $130,418 10 0.22
Full Professor female $100,572 $140,930 $181,288 2 0.04
Associate Professor male $ 98,246 $101,605 $106,640 3 0.07
Associate Professor female $ 97,998 $101,527 $112,264 3 0.07
Associate Professor uncoded $102,156 $102,938 $103,720 2 0.04
Assistant Professor male $ 84,500 $ 85,308 $ 86,211 4 0.09
Assistant Professor female $ 85,526 $ 86,000 $ 87,750 3 0.07
Assistant Professor uncoded $ 85,000 $ 85,000 $ 85,000 1 0.02
Teaching Faculty male $ 55,000 $ 55,000 $ 57,752 3 0.07
Teaching Faculty female $ 60,547 $ 60,547 $ 60,547 1 0.02
Teaching Faculty uncoded $ 49,479 $ 49,479 $ 49,479 1 0.02
Researcher male $ 45,019 $ 52,500 $ 60,000 4 0.09
Researcher female $ 37,017 $ 40,128 $ 45,540 4 0.09
Researcher uncoded $ 50,000 $ 50,000 $ 50,000 5 0.11



School of Math & Stat Sciences

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Mahalov, Alex male Professor $224,020
McCulloch, Robert male Professor $212,170
Renaut, Rosemary female Professor $174,005
Gumel, Abba male Professor $167,945
Carlson, Marilyn female Professor $164,207

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $125,180 $136,726 $153,320 19 0.19
Full Professor female $144,838 $164,207 $169,106 3 0.03
Full Professor uncoded $132,695 $132,695 $132,695 1 0.01
Associate Professor male $ 96,670 $104,980 $110,148 15 0.15
Associate Professor female $ 93,844 $ 97,091 $ 98,876 4 0.04
Associate Professor uncoded $ 99,722 $104,744 $108,216 3 0.03
Assistant Professor male $ 92,781 $101,600 $105,000 5 0.05
Assistant Professor female $105,000 $105,000 $105,000 1 0.01
Assistant Professor uncoded $ 92,500 $ 95,000 $ 97,500 3 0.03
Teaching Faculty male $ 50,470 $ 59,955 $ 60,444 17 0.17
Teaching Faculty female $ 55,000 $ 57,390 $ 61,038 9 0.09
Teaching Faculty uncoded $ 55,000 $ 57,658 $ 65,626 8 0.08
Researcher male $ 53,250 $ 54,000 $ 55,114 7 0.07
Researcher female $ 66,882 $ 80,064 $ 93,245 2 0.02
Researcher uncoded $ 54,000 $ 54,000 $ 54,000 1 0.01



School of Molecular Sciences

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Navrotsky, Alexandra female Professor $240,000
Fromme, Petra female Regents Professor $226,197
Angell, Charles male Regents Professor $191,976
Moore, Thomas male Regents Professor $184,096
Yarger, Jeffery male Professor $176,161

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $125,521 $135,675 $149,260 17 0.19
Full Professor female $142,128 $159,551 $226,197 5 0.05
Full Professor uncoded $127,221 $128,007 $134,869 3 0.03
Associate Professor male $103,056 $103,495 $105,099 5 0.05
Associate Professor female $101,409 $101,409 $101,409 1 0.01
Assistant Professor male $ 94,569 $ 95,524 $ 96,478 6 0.07
Assistant Professor female $ 93,000 $ 94,000 $ 94,856 3 0.03
Assistant Professor uncoded $ 96,478 $ 96,478 $ 96,478 1 0.01
Teaching Faculty male $ 46,430 $ 47,918 $ 48,700 6 0.07
Teaching Faculty female $ 47,425 $ 48,723 $ 56,010 11 0.12
Teaching Faculty uncoded $ 46,500 $ 47,999 $ 48,246 3 0.03
Researcher male $ 50,201 $ 55,977 $ 88,750 12 0.13
Researcher female $ 47,607 $ 50,680 $ 67,000 10 0.11
Researcher uncoded $ 39,244 $ 48,960 $ 54,428 8 0.09



School of Politics & Global St

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Hero, Rodney male Professor $341,750
Polt, Michael male Professor of Practice (FSC) $226,600
Thies, Cameron male Professor $175,000
Hechter, Michael male Professor $171,750
Bergen, Peter male Professor of Practice (FSC) $157,500

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $112,700 $171,750 $175,000 5 0.14
Full Professor female $131,875 $139,000 $146,125 2 0.05
Associate Professor male $100,500 $101,750 $102,000 5 0.14
Associate Professor female $ 85,750 $ 96,000 $ 99,772 6 0.16
Assistant Professor male $ 85,000 $ 86,750 $ 99,125 4 0.11
Assistant Professor female $ 88,750 $ 92,000 $ 95,250 2 0.05
Assistant Professor uncoded $ 85,000 $ 85,000 $ 85,000 1 0.03
Teaching Faculty male $ 56,500 $119,500 $154,500 8 0.22
Teaching Faculty female $ 56,625 $ 58,250 $ 81,875 3 0.08
Researcher female $ 60,000 $ 60,000 $ 60,000 1 0.03



School Of Public Affairs

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Bozeman, Barry male Regents Professor $236,900
Kapstein, Ethan male Professor $227,500
Reilly, Thomas male Professor $186,375
Corley, Elizabeth female Professor $150,070
Feeney, Mary female Professor $144,000

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $ 92,261 $186,375 $227,500 5 0.20
Full Professor female $145,518 $147,035 $148,552 2 0.08
Associate Professor male $102,820 $104,725 $113,488 4 0.16
Associate Professor uncoded $106,496 $106,496 $106,496 1 0.04
Assistant Professor male $ 92,150 $ 94,200 $ 94,600 3 0.12
Assistant Professor female $ 90,125 $ 92,250 $ 94,375 2 0.08
Assistant Professor uncoded $ 88,500 $ 88,500 $ 88,500 1 0.04
Teaching Faculty male $ 30,950 $ 40,300 $ 49,700 4 0.16
Teaching Faculty female $ 40,195 $ 49,000 $ 62,000 3 0.12



School of Social Transform

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Brayboy, Bryan male President’s Professor $219,429
Scott, Kimberly female Professor $180,000
Lomawaima, K uncoded Professor $161,685
Moore, Elsie female Professor $148,250
Gonzales, Angela female Assoc Professor $143,200

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $154,309 $176,016 $197,722 2 0.04
Full Professor female $ 98,345 $109,370 $119,745 8 0.16
Full Professor uncoded $161,685 $161,685 $161,685 1 0.02
Associate Professor male $ 85,536 $ 90,000 $100,738 9 0.18
Associate Professor female $ 83,312 $ 92,394 $ 99,673 14 0.27
Associate Professor uncoded $100,673 $100,673 $100,673 1 0.02
Assistant Professor male $ 58,750 $ 67,500 $ 76,250 2 0.04
Assistant Professor female $ 85,000 $ 85,000 $ 85,000 5 0.10
Assistant Professor uncoded $ 85,000 $ 85,000 $ 85,000 1 0.02
Teaching Faculty male $ 53,460 $ 54,171 $ 54,882 2 0.04
Teaching Faculty female $ 39,538 $ 45,000 $ 52,422 3 0.06
Teaching Faculty uncoded $ 45,000 $ 45,000 $ 45,000 1 0.02
Researcher female $ 70,343 $ 70,343 $ 70,343 1 0.02
Researcher uncoded $ 42,500 $ 42,500 $ 42,500 1 0.02



School Of Social Work

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Messing, Jill female Professor $160,000
Shafer, Michael male Professor $137,401
Ashford, Jose male Professor $131,845
Segal, Elizabeth female Professor $130,390
Lecroy, Craig male Professor $129,970

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $127,502 $130,908 $133,234 4 0.06
Full Professor female $123,725 $130,390 $145,195 3 0.05
Associate Professor male $ 91,649 $ 92,864 $ 94,078 2 0.03
Associate Professor female $ 90,194 $ 90,267 $ 91,528 5 0.08
Assistant Professor male $ 82,250 $ 83,500 $ 84,750 2 0.03
Assistant Professor female $ 83,000 $ 83,550 $ 83,750 10 0.16
Assistant Professor uncoded $ 82,425 $ 83,000 $ 84,700 4 0.06
Teaching Faculty male $ 35,725 $ 48,450 $ 49,800 3 0.05
Teaching Faculty female $ 48,200 $ 50,750 $ 53,710 26 0.41
Researcher male $ 60,000 $ 60,000 $ 60,000 1 0.02
Researcher female $ 51,885 $ 64,000 $ 66,250 4 0.06



SHPRS History Faculty

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Fixico, Donald male Regents Professor $271,527
Austin, Curtis male Assoc Professor $190,000
Alexander, Leslie female Assoc Professor $190,000
Saikia, Yasmin female Professor $181,750
Critchlow, Donald male Professor $158,446

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $101,565 $130,000 $158,446 5 0.12
Full Professor female $130,808 $147,789 $164,770 2 0.05
Full Professor uncoded $135,206 $135,206 $135,206 1 0.02
Associate Professor male $108,000 $108,707 $122,268 5 0.12
Associate Professor female $ 75,612 $ 91,369 $104,841 7 0.17
Assistant Professor male $ 75,741 $ 76,732 $ 78,241 3 0.07
Assistant Professor female $ 77,506 $ 79,750 $ 79,875 3 0.07
Assistant Professor uncoded $ 82,494 $ 82,494 $ 82,494 1 0.02
Teaching Faculty male $ 50,575 $ 51,000 $ 67,667 9 0.21
Teaching Faculty female $ 49,429 $ 58,334 $ 67,959 4 0.10
Teaching Faculty uncoded $ 47,992 $ 47,992 $ 47,992 1 0.02
Researcher female $ 60,000 $ 60,000 $ 60,000 1 0.02



Social & Behavioral Sciences

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Mickelson, Kristin female Professor $125,464
Kassing, Jeffrey male Professor $118,412
Kirby, Andrew male Professor $117,816
Nadesan, Majia uncoded Professor $114,104
Waldron, Vincent male Professor $108,184

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $103,368 $106,592 $115,408 6 0.09
Full Professor female $125,464 $125,464 $125,464 1 0.01
Full Professor uncoded $114,104 $114,104 $114,104 1 0.01
Associate Professor male $ 93,394 $ 97,660 $ 99,152 5 0.07
Associate Professor female $ 91,490 $ 93,801 $ 98,000 9 0.13
Assistant Professor male $ 83,562 $ 85,625 $ 87,438 4 0.06
Assistant Professor female $ 81,000 $ 82,987 $ 85,000 8 0.12
Assistant Professor uncoded $ 82,500 $ 82,500 $ 82,500 1 0.01
Teaching Faculty male $ 48,224 $ 54,000 $ 54,000 9 0.13
Teaching Faculty female $ 52,000 $ 54,000 $ 55,000 19 0.28
Teaching Faculty uncoded $ 54,000 $ 54,000 $ 54,000 1 0.01
Researcher female $ 48,750 $ 52,810 $ 56,715 4 0.06



Sols Administration & Faculty

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Grimm, Nancy female Regents Professor $253,500
Compton, Carolyn female Professor $241,600
Jacobs, Bertram male Professor $202,800
Perrings, Charles male Professor $188,538
Collins, James male Professor $186,576

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $119,282 $131,002 $158,089 21 0.18
Full Professor female $123,004 $146,298 $158,500 11 0.09
Full Professor uncoded $ 97,221 $114,018 $130,814 2 0.02
Associate Professor male $ 98,827 $105,545 $123,339 10 0.09
Associate Professor female $102,720 $110,150 $118,748 4 0.03
Associate Professor uncoded $ 99,294 $102,819 $106,344 2 0.02
Assistant Professor male $ 90,550 $ 93,700 $ 96,850 2 0.02
Assistant Professor female $ 92,000 $ 94,000 $ 94,150 7 0.06
Assistant Professor uncoded $ 99,000 $ 99,000 $ 99,000 1 0.01
Teaching Faculty male $ 48,000 $ 48,000 $ 56,875 7 0.06
Teaching Faculty female $ 48,000 $ 48,000 $ 53,150 8 0.07
Researcher male $ 50,123 $ 52,000 $ 58,260 17 0.15
Researcher female $ 49,500 $ 51,638 $ 64,250 16 0.14
Researcher uncoded $ 47,494 $ 50,678 $ 55,414 8 0.07



SOS Faculty & Researchers

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Pfirman, Stephanie female Professor $255,000
Melnick, Robert male Research Scientist $249,765
Basile, George male Professor of Practice (FSC) $168,913
Childers, Daniel male Professor $145,466
Aggarwal, Rimjhim uncoded Assoc Professor $143,500

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $ 88,528 $110,980 $131,516 4 0.08
Full Professor female $123,124 $126,249 $190,624 3 0.06
Full Professor uncoded $118,827 $118,827 $118,827 1 0.02
Associate Professor male $ 97,101 $ 97,515 $ 97,929 2 0.04
Associate Professor female $ 98,982 $ 99,813 $100,644 2 0.04
Associate Professor uncoded $143,500 $143,500 $143,500 1 0.02
Assistant Professor male $ 78,184 $ 89,251 $101,164 4 0.08
Assistant Professor female $ 87,116 $ 87,125 $102,562 3 0.06
Assistant Professor uncoded $ 87,333 $ 87,966 $ 88,600 2 0.04
Teaching Faculty male $ 46,250 $ 51,129 $ 59,771 10 0.20
Teaching Faculty female $ 38,655 $ 45,000 $ 45,000 11 0.22
Teaching Faculty uncoded $ 27,000 $ 50,000 $ 52,632 5 0.10
Researcher male $103,691 $152,382 $201,074 2 0.04



The Design School

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Jackson, Maria female Professor $142,011
Underhill, Michael male Professor $135,995
Brooks, Kenneth male Professor $133,800
Petrucci, Darren male Professor $132,762
Reddy, T Agami uncoded Professor $128,056

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $106,867 $122,233 $133,281 7 0.14
Full Professor female $142,011 $142,011 $142,011 1 0.02
Full Professor uncoded $128,056 $128,056 $128,056 1 0.02
Associate Professor male $ 80,020 $ 81,763 $ 83,445 9 0.18
Associate Professor female $ 80,173 $ 91,695 $103,351 5 0.10
Associate Professor uncoded $ 82,032 $ 82,032 $ 82,032 1 0.02
Assistant Professor male $ 70,250 $ 70,500 $ 70,750 3 0.06
Assistant Professor female $ 70,700 $ 70,700 $ 70,700 1 0.02
Assistant Professor uncoded $ 70,500 $ 71,000 $ 71,375 3 0.06
Teaching Faculty male $ 43,212 $ 48,100 $ 61,722 8 0.16
Teaching Faculty female $ 32,236 $ 50,900 $ 66,225 10 0.20



The Sanford School

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Elliott, Stephen male Professor $281,860
Sandefur, Rebecca female Professor $220,000
Fabes, Richard male Professor $190,000
Meek, Shantel female Professor of Practice (FSC) $168,093
Ladd, Gary male Professor $165,726

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $124,358 $158,364 $183,932 6 0.13
Full Professor female $122,326 $127,953 $132,502 7 0.15
Associate Professor male $ 98,500 $ 98,500 $ 98,500 1 0.02
Associate Professor female $ 99,132 $100,255 $116,712 8 0.17
Assistant Professor male $ 86,212 $ 86,775 $ 87,338 2 0.04
Assistant Professor female $ 85,529 $ 87,358 $ 88,800 6 0.13
Teaching Faculty male $ 24,814 $ 24,814 $ 24,814 1 0.02
Teaching Faculty female $ 82,609 $ 82,609 $ 88,433 5 0.11
Teaching Faculty uncoded $ 49,300 $ 49,300 $ 49,300 1 0.02
Researcher male $113,603 $113,603 $113,603 1 0.02
Researcher female $ 52,500 $ 52,500 $ 59,282 7 0.15
Researcher uncoded $ 53,375 $ 54,250 $ 55,125 2 0.04



WPC Accountancy

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Lamoreaux, Phillip male Assoc Professor $323,113
Li, Yinghua uncoded Professor $322,573
Matejka, Michal female Professor $309,350
Reckers, Philip male Professor $300,975
Kaplan, Steven male Professor $297,109

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $248,620 $297,109 $299,042 3 0.08
Full Professor female $309,350 $309,350 $309,350 1 0.03
Full Professor uncoded $174,393 $223,786 $273,180 2 0.05
Associate Professor male $224,344 $262,454 $280,428 4 0.10
Associate Professor female $267,244 $274,394 $278,578 4 0.10
Associate Professor uncoded $265,220 $265,220 $265,220 1 0.03
Assistant Professor male $217,494 $219,475 $221,306 6 0.15
Assistant Professor female $215,475 $215,475 $215,475 1 0.03
Assistant Professor uncoded $225,000 $225,000 $225,000 1 0.03
Teaching Faculty male $ 88,676 $ 98,550 $129,500 8 0.21
Teaching Faculty female $ 96,612 $120,650 $143,750 8 0.21



WPC Economics

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Prescott, Edward male Regents Professor $340,159
Manelli, Alejandro male Professor $320,449
Silverman, Daniel male Professor $310,840
Chade, Hector male Professor $302,410
Mehra, Rajnish uncoded Professor $296,743

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $178,508 $246,564 $302,410 13 0.30
Full Professor female $180,091 $180,091 $180,091 1 0.02
Full Professor uncoded $296,743 $296,743 $296,743 1 0.02
Associate Professor male $172,974 $183,753 $184,974 6 0.14
Associate Professor female $149,103 $153,830 $158,558 2 0.05
Associate Professor uncoded $107,984 $107,984 $107,984 1 0.02
Assistant Professor male $147,288 $154,000 $157,750 4 0.09
Assistant Professor female $147,433 $152,288 $157,144 2 0.05
Teaching Faculty male $ 93,993 $101,038 $104,520 8 0.19
Teaching Faculty female $102,700 $104,300 $105,800 4 0.09
Researcher male $111,706 $111,706 $111,706 1 0.02



WPC Information Systems

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Chen, Pei-yu uncoded Professor $230,917
Zhang, Zhongju uncoded Professor $224,029
Shao, Benjamin male Professor $209,807
Shi, Zhan uncoded Assoc Professor $200,867
Han, Sang Pil male Assoc Professor $195,019

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $130,719 $157,082 $183,444 2 0.06
Full Professor uncoded $225,751 $227,473 $229,195 2 0.06
Associate Professor male $177,755 $183,510 $189,264 2 0.06
Associate Professor uncoded $178,106 $185,693 $193,280 2 0.06
Assistant Professor male $168,039 $168,039 $168,039 1 0.03
Assistant Professor female $168,151 $172,100 $176,050 2 0.06
Assistant Professor uncoded $180,000 $180,000 $180,000 1 0.03
Teaching Faculty male $ 84,549 $ 95,000 $120,000 13 0.36
Teaching Faculty female $ 75,056 $ 93,905 $124,146 4 0.11
Teaching Faculty uncoded $ 86,008 $100,000 $103,666 7 0.19



WPC Management

TOP FIVE SALARIES

Full.Name gender Job.Description salary
LePine, Jeffery male Professor $402,257
Gomez-Mejia, Luis male Regents Professor $361,393
Ashforth, Blake male Regents Professor $338,580
Corley, Kevin male Professor $282,000
Semadeni, Matthew male Professor $273,267

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $219,152 $282,000 $349,986 7 0.17
Associate Professor male $195,430 $228,780 $232,799 8 0.20
Associate Professor female $144,591 $155,322 $168,114 4 0.10
Assistant Professor female $215,000 $215,000 $215,000 1 0.02
Assistant Professor uncoded $163,151 $163,151 $163,151 1 0.02
Teaching Faculty male $ 85,680 $ 97,549 $119,294 13 0.32
Teaching Faculty female $ 97,174 $103,807 $106,524 5 0.12
Teaching Faculty uncoded $122,520 $122,520 $122,520 1 0.02
Researcher male $ 47,208 $ 47,208 $ 47,208 1 0.02



WPC Supply Chain Management

TOP FIVE SALARIES

Full.Name gender Job.Description salary
Choi, Thomas male Professor $288,818
Carter, Craig male Professor $263,000
Fowler, John male Professor $256,139
Rabinovich, Elliot male Professor $252,685
Li, Hongmin uncoded Professor $250,000

PAY RANGE BY RANK AND GENDER

title gender q25 q50 q75 n p
Full Professor male $217,774 $244,224 $256,139 9 0.30
Full Professor uncoded $250,000 $250,000 $250,000 1 0.03
Associate Professor male $183,522 $185,682 $187,841 2 0.07
Associate Professor uncoded $167,055 $178,720 $180,270 3 0.10
Assistant Professor male $154,050 $160,000 $165,000 3 0.10
Assistant Professor female $148,601 $148,601 $148,601 1 0.03
Teaching Faculty male $ 91,750 $ 98,512 $117,578 7 0.23
Teaching Faculty female $ 89,478 $ 90,457 $ 91,436 2 0.07
Teaching Faculty uncoded $103,104 $106,207 $109,310 2 0.07