DC Government Employee Salary Data

Washington, DC

Making Sense of DC’s Public Salary Data

In the interest of transparency, most government institutions post the salary data of their employees, so that the public can have insight and visibility into where their tax dollars are going. FederalPay.org in particular is a great resource to look up the salaries of federal employees. However, this same set of tools does not typically exist for local and state governments.

In the case of the District of Columbia, the DC Department of Human Resources posts a quarterly update of public employee salary information in PDF form. While useful, this information is quite unwieldy - there are over 36,000 rows and there aren’t any easy ways to manipulate or aggregate the data beyond simple search.

To make this information more interactive and useful to the public, I’ve extracted the data from DCHR’s PDF, cleansed it in R, and loaded it into an interactive Shiny application, which is search and sort-able. Check out the tool at the link, and also embedded below!

Highlights

  • Total Employees: 36,023
  • Median Tenure: 8 years
  • Mean Tenure: 10.4 years
  • Median Compensation: $71,477
  • Mean Compensation: $74,103
  • Max Compensation: $312,965

Code for the App

global.R

library(readr)
salaries <-
  read_csv("dc_salaries_03312018.csv",
           col_types = cols(`Hire Date` = col_date(format = "%Y-%m-%d"),
                            X1 = col_skip(), Grade = col_skip()))

ui.R

library(shiny)

shinyUI(fluidPage(
  title = 'Searchable DC Public Employee Database',
  h1('DC Public Employee Salary Information'),
  h4('A searchable database of publicly listed DC Government salary data and job information'),
  h5('Last updated March 31, 2018 by the DC Department of Human Resources'),
  fluidRow(
    column(12, DT::dataTableOutput('tbl'))
  )
))

server.R

library(shiny)
library(DT)

shinyServer(function(input, output, session) {
  output$tbl = DT::renderDataTable(
    datatable(salaries) %>% formatCurrency('Compensation'),
    rownames = FALSE,
    extensions = c("Buttons", "FixedHeader", "Responsive"),
    options = list(
      searchHighlight = TRUE,
      search = list(caseInsensitive = TRUE),
      autoWidth = TRUE,
      style = "width:100%"
    ) 
 )
  })