Code
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)library(tidyverse)
library(gt)
library(gtExtras)
b_jobs <- read_csv("https://jsuleiman.com/datasets/me_grad_employment.csv") |>
mutate(
growth_rate = parse_number(growth_rate) / 100,
)
b_jobs_table <- b_jobs |>
select(occupation, base_employment, projected_employment, growth_rate, annual_openings, median_wage, entry_wage) |>
gt() |>
tab_header(
title = "Occupational Employment in Maine",
subtitle = "Jobs Requiring a Master's, Doctoral, or Professional Degree"
) |>
fmt_number(columns = c(base_employment, projected_employment, annual_openings), sep_mark = ",", decimals = 0) |>
fmt_percent(columns = growth_rate, decimals = 2) |>
fmt_currency(columns = c(median_wage, entry_wage), currency = "USD") |>
tab_style(
style = cell_text(weight = "bold"),
locations = cells_column_labels()
) |>
tab_style(
style = cell_borders(sides = "bottom", color = "gray", weight = px(1)),
locations = cells_column_labels()
) |>
cols_align(align = "right", columns = c(base_employment, projected_employment, annual_openings, median_wage, entry_wage)) |>
cols_align(align = "left", columns = occupation) |>
fmt_number(columns = growth_rate, decimals = 2) |>
tab_style(
style = cell_text(weight = "bold", color = "blue"),
locations = cells_body(columns = growth_rate, rows = growth_rate > 0.05)
) |>
tab_source_note("Data Source: Maine Department of Labor")
b_jobs_table| Occupational Employment in Maine | ||||||
|---|---|---|---|---|---|---|
| Jobs Requiring a Master's, Doctoral, or Professional Degree | ||||||
| occupation | base_employment | projected_employment | growth_rate | annual_openings | median_wage | entry_wage |
| Lawyers | 2,725 | 2,862 | 0.05 | 121 | $98760 | $66090 |
| Educational, Guidance, and Career Counselors and Advisors | 1,679 | 1,712 | 0.02 | 122 | $56780 | $42910 |
| Education Administrators, Kindergarten through Secondary | 1,673 | 1,683 | 0.01 | 111 | $98800 | $74900 |
| Physical Therapists | 1,580 | 1,667 | 0.06 | 71 | $90590 | $75330 |
| Mental Health and Substance Abuse Social Workers | 1,459 | 1,460 | 0.00 | 100 | $66380 | $49370 |
| Pharmacists | 1,366 | 1,388 | 0.02 | 53 | $135430 | $102210 |
| Nurse Practitioners | 1,332 | 1,804 | 0.35 | 117 | $123140 | $99830 |
| Occupational Therapists | 1,161 | 1,200 | 0.03 | 68 | $79700 | $63760 |
| Librarians and Media Collections Specialists | 914 | 904 | −0.01 | 83 | $59010 | $41020 |
| Instructional Coordinators | 895 | 895 | 0.00 | 76 | $73760 | $53990 |
| Psychologists, All Other | 893 | 920 | 0.03 | 60 | $85520 | $62970 |
| Physician Assistants | 795 | 971 | 0.22 | 61 | $131540 | $109100 |
| Speech-Language Pathologists | 764 | 852 | 0.12 | 52 | $80210 | $60110 |
| Education Administrators, Postsecondary | 752 | 738 | −0.02 | 48 | $82460 | $60440 |
| Health Specialties Teachers, Postsecondary | 706 | 797 | 0.13 | 67 | $84500 | $59510 |
| Art, Drama, and Music Teachers, Postsecondary | 587 | 575 | −0.02 | 45 | $78380 | $51380 |
| Veterinarians | 536 | 571 | 0.07 | 22 | $128240 | $90250 |
| Healthcare Social Workers | 484 | 495 | 0.02 | 42 | $64040 | $54770 |
| Acupuncturists | 432 | 432 | 0.00 | 26 | $65040 | $44520 |
| English Language and Literature Teachers, Postsecondary | 428 | 411 | −0.04 | 30 | $81960 | $61310 |
| Biochemists and Biophysicists | 414 | 388 | −0.06 | 25 | $84440 | $67990 |
| Education Teachers, Postsecondary | 410 | 404 | −0.01 | 31 | $76480 | $51410 |
| Nursing Instructors and Teachers, Postsecondary | 404 | 452 | 0.12 | 38 | $77370 | $55710 |
| Postsecondary Teachers, All Other | 378 | 371 | −0.02 | 28 | $72170 | $43980 |
| Business Teachers, Postsecondary | 309 | 313 | 0.01 | 24 | $81340 | $56730 |
| Biological Science Teachers, Postsecondary | 303 | 311 | 0.03 | 25 | $79220 | $59190 |
| Data Source: Maine Department of Labor | ||||||
In this section, I will describe how I implemented each of the six required rules from Chapter 11 and the formatting decisions I made for the occupational employment table for jobs requiring a master’s, doctoral, or professional degree in Maine. The goal was to create a clear, legible table that adheres to Schwabish’s guidelines for better tables, ensuring that important trends are easy to spot and the table overall is easy to interpret.
Make column headers distinct from the data using boldface text or lines to clearly separate them.
To implement Rule 1, I made the column headers bold to offset them from the body of the table. This visual distinction makes it clear that the headers are categories (such as “Occupation” and “Growth Rate”) and not data values. The bolded headers help the reader quickly navigate the table by separating the metadata (headers) from the numerical data.
Lighten or remove heavy gridlines, using subtle dividers or shading to separate important data without creating visual clutter.
For Rule 2, I replaced heavy gridlines with subtle dividers between rows and columns. Specifically, I used thin gray borders to separate the headers and data. This reduces visual clutter and enhances readability by allowing the reader to focus on the data without being distracted by excessive lines. I also ensured that the table’s readability was maintained by only applying borders to the necessary elements.
Align numbers to the right to make it easier to compare values. Ensure that the column headers are also right-aligned with the numbers.
To implement Rule 3, I right-aligned all numeric columns in the table, including base employment, projected employment, annual openings, median wage, and entry wage. Right alignment helps the reader easily compare numbers, especially for large values, as it ensures that digits are properly aligned by their decimal point or comma. This improves the legibility of the numeric data and allows for easier visual comparisons across rows.
Left-align text in the table for readability, making it easier for the reader to scan labels or text entries.
For Rule 4, I left-aligned the occupation column. This is the natural alignment for textual data in tables, as it makes it easier to scan and read the occupation names. Left alignment also ensures that the text is aligned consistently, creating a clean visual structure for the reader.
Avoid over-precision in numbers, and balance between adequate detail and a clean, readable table.
For Rule 5, I limited the growth rate to two decimal places. The growth rate was initially in percentage form (e.g., 5% for .05) rather than decimal format. Since the data was in decimal format, I decided that two decimal places provided an appropriate level of precision for the growth rate. This ensures that the values are clear and concise without unnecessary detail, which would otherwise clutter the table.
Highlight outliers or important data points using bold text or shading to make them stand out and capture the reader’s attention.
To implement Rule 8, I identified and highlighted outlier occupations based on their growth rate. Specifically, I focused on occupations where the growth rate was greater than 5%, or 0.05. These occupations were highlighted in blue text for quick identification. Of the 26 occupations in the dataset, 7 had growth rates above 5%. The following occupations had the highest growth rates:
Physical Therapists (6% growth rate)
Nurse Practitioners (35% growth rate)
Physician Assistants (22% growth rate)
Speech-Language Pathologists (12% growth rate)
Health Specialties Teachers, Postsecondary (13% growth rate)
Veterinarians (7% growth rate)
Nursing Instructors and Teachers, Postsecondary (12% growth rate)
Among these, Nurse Practitioners had the highest growth rate of 35%, with base employment of 1,332 in 2020 and projected employment of 1804 in 2030. Highlighting these outliers helps the reader quickly identify the fastest-growing occupations, which could be of particular interest to anyone exploring job trends in Maine.
I used ChatGPT to draft the report structure, brainstorm visualization choices, and refine analysis language. Here is the transcript.
make me a table using r with 7 columns and 26 rows
Here’s an R code snippet to create a table with 7 columns and 26 rows. You can run this in your R environment:
R
CopyEdit
# Create an empty data frame with 26 rows and 7 columns table_data <- data.frame(matrix(ncol = 7, nrow = 26)) # Assign column names colnames(table_data) <- c("Column1", "Column2", "Column3", "Column4", "Column5", "Column6", "Column7") # View the table print(table_data)
This code creates a table with 7 columns and 26 rows, where the columns are named Column1, Column2, etc. You can modify the column names and fill in the table with actual data as needed.