Project 2 — Data Tidying

Author

Lionel jr. desroses

Published

October 10, 2026

Introduction

Project Overview

For this project, I plan to work with three independent education-related datasets that can be linked together using the state as a common identifier. The datasets will focus on high school graduation rates, state-level SAT scores, and state-level public education funding. Although each dataset will be analyzed separately as required by the assignment, they all relate to educational outcomes and provide an opportunity to explore broader relationships between academic performance, graduation rates, and school funding.

The goal of this project is to demonstrate how to transform wide-format data into tidy data using the tidyr and dplyr packages in R. After tidying each dataset, I will perform exploratory analyses, create summary tables, and develop visualizations that highlight patterns within each dataset. Finally, I will combine the tidy datasets to investigate whether states with higher education funding also tend to have higher SAT scores and graduation rates.

Proposed Approach

Dataset 1: High School Graduation Rates

The first dataset will contain high school graduation rates by state. Since educational datasets are often stored in wide format, with years as separate columns, I expect to use pivot_longer() to transform the data into a tidy structure, where each row represents a state-year observation.After tidying the data, I will create summary tables showing graduation rates by state and identify the states with the highest graduation rates. I will also develop visualizations, such as bar charts, to compare graduation rates across states and highlight the highest-performing states.

Dataset 2: SAT Scores by State

The second dataset will contain SAT scores by state. Similar to the graduation dataset, I expect the data may require reshaping and standardizing variable names before analysis.Once the data has been tidied, I will calculate summary statistics and identify which states have the highest average SAT scores. I will then create visualizations to compare SAT performance across states and identify notable patterns or trends.

Dataset 3: Public Education Funding

The third dataset will focus on public education funding by state, including per-pupil expenditures and total education spending. This dataset may contain multiple funding categories that will need to be transformed into a tidy format. After cleaning and restructuring the data, I will create summary tables showing the states with the highest education spending and generate visualizations that compare funding levels across states.

Combined Analysis

After completing the required analysis for each dataset, I plan to merge the three tidy datasets using the state as the common key. This additional analysis will allow me to explore potential relationships among education funding, SAT scores, and graduation rates.

Specifically, I will investigate questions such as:

Expected Challenges

One challenge will be ensuring that all three datasets use a consistent state identifier. Some datasets may use full state names while others may use abbreviations, requiring additional data cleaning before the datasets can be merged.

.

Running Code

library(tidyverse)
library(tidyr)
library(dplyr)
library(ggplot2)
library(tibble)

Dataset 1: High School Graduation Rates

The original graduation-rate dataset was stored in a wide format where states appeared as column names and graduation years appeared as rows. This structure made analysis difficult because years were stored as observations rather than variables. To create a tidy dataset, the data was first transposed so that each state became a row and each graduation year became a column. The dataset was then reshaped into a long format using pivot_longer(), producing one row per state-year combination.

library(readr)
HS_grad_rate <- read_csv("https://raw.githubusercontent.com/lioneljr17/LDATA607/refs/heads/main/Project2/HS_grad_rate.csv")
#View(HS_grad_rate)

dim(HS_grad_rate)
[1]  5 53
names(HS_grad_rate)
 [1] "state"                "Vermont"              "Maine"               
 [4] "Montana"              "New Hampshire"        "Wyoming"             
 [7] "North Dakota"         "Minnesota"            "Alaska"              
[10] "Wisconsin"            "Utah"                 "Iowa"                
[13] "Hawaii"               "South Dakota"         "Colorado"            
[16] "District of Columbia" "Washington"           "Nebraska"            
[19] "Michigan"             "Pennsylvania"         "Kansas"              
[22] "Idaho"                "Missouri"             "Ohio"                
[25] "Oregon"               "Delaware"             "Virginia"            
[28] "Connecticut"          "Massachusetts"        "Maryland"            
[31] "New Jersey"           "Illinois"             "Indiana"             
[34] "North Carolina"       "South Carolina"       "Tennessee"           
[37] "Florida"              "Rhode Island"         "Arizona"             
[40] "Oklahoma"             "West Virginia"        "Georgia"             
[43] "Kentucky"             "Arkansas"             "Alabama"             
[46] "New Mexico"           "New York"             "Nevada"              
[49] "Louisiana"            "Mississippi"          "Texas"               
[52] "California"           "United States"       
head(HS_grad_rate)
# A tibble: 5 × 53
  state   Vermont Maine Montana `New Hampshire` Wyoming `North Dakota` Minnesota
  <chr>     <dbl> <dbl>   <dbl>           <dbl>   <dbl>          <dbl>     <dbl>
1 HighSc…    94.9  94.8    94.6            94.4    94.2           94        93.9
2 HighSc…    94.5  94.5    94.6            94.1    94.1           93.8      93.9
3 HighSc…    94.2  94.1    94.5            93.8    93.9           93.5      93.7
4 HighSc…    93.9  93.7    94.4            93.6    93.7           93.3      93.6
5 HighSc…    93.5  93.2    94              93.3    93.6           93.1      93.4
# ℹ 45 more variables: Alaska <dbl>, Wisconsin <dbl>, Utah <dbl>, Iowa <dbl>,
#   Hawaii <dbl>, `South Dakota` <dbl>, Colorado <dbl>,
#   `District of Columbia` <dbl>, Washington <dbl>, Nebraska <dbl>,
#   Michigan <dbl>, Pennsylvania <dbl>, Kansas <dbl>, Idaho <dbl>,
#   Missouri <dbl>, Ohio <dbl>, Oregon <dbl>, Delaware <dbl>, Virginia <dbl>,
#   Connecticut <dbl>, Massachusetts <dbl>, Maryland <dbl>, `New Jersey` <dbl>,
#   Illinois <dbl>, Indiana <dbl>, `North Carolina` <dbl>, …
grad_clean <- HS_grad_rate %>%
  column_to_rownames("state") %>%
  t() %>%
  as.data.frame() %>%
  rownames_to_column("state")

names(grad_clean) <- c(
  "state",
  "highschool_2024",
  "highschool_2023",
  "highschool_2022",
  "highschool_2021",
  "highschool_2020"
)

grad_tidy <- grad_clean %>%
  pivot_longer(
    starts_with("highschool_"),
    names_to = "year",
    values_to = "graduation_rate"
  ) %>%
  mutate(
    year = gsub("highschool_", "", year),
    graduation_rate = as.numeric(graduation_rate)
  )
top5_grad <- grad_clean %>%
  arrange(desc(highschool_2024)) %>%
  slice_head(n = 5)

top5_grad
          state highschool_2024 highschool_2023 highschool_2022 highschool_2021
1       Vermont            94.9            94.5            94.2            93.9
2         Maine            94.8            94.5            94.1            93.7
3       Montana            94.6            94.6            94.5            94.4
4 New Hampshire            94.4            94.1            93.8            93.6
5       Wyoming            94.2            94.1            93.9            93.7
  highschool_2020
1            93.5
2            93.2
3            94.0
4            93.3
5            93.6
bottom5_grad <- grad_clean %>%
  arrange(highschool_2024) %>%
  slice_head(n = 5)

bottom5_grad
        state highschool_2024 highschool_2023 highschool_2022 highschool_2021
1  California            84.7            84.6            84.4            84.2
2       Texas            86.0            85.7            85.2            84.8
3 Mississippi            87.1            86.6            86.2            85.6
4   Louisiana            87.3            86.9            86.7            86.2
5      Nevada            87.5            87.4            87.1            87.0
  highschool_2020
1            83.9
2            84.4
3            85.3
4            85.9
5            86.9
grad_clean %>%
  arrange(desc(highschool_2024)) %>%
  slice_head(n = 10)
           state highschool_2024 highschool_2023 highschool_2022
1        Vermont            94.9            94.5            94.2
2          Maine            94.8            94.5            94.1
3        Montana            94.6            94.6            94.5
4  New Hampshire            94.4            94.1            93.8
5        Wyoming            94.2            94.1            93.9
6   North Dakota            94.0            93.8            93.5
7      Minnesota            93.9            93.9            93.7
8         Alaska            93.6            93.5            93.5
9      Wisconsin            93.6            93.4            93.1
10          Utah            93.4            93.3            93.2
   highschool_2021 highschool_2020
1             93.9            93.5
2             93.7            93.2
3             94.4            94.0
4             93.6            93.3
5             93.7            93.6
6             93.3            93.1
7             93.6            93.4
8             93.3            93.1
9             92.9            92.6
10            93.1            93.0
  grad_clean %>%
  arrange(desc(highschool_2024)) %>%
  slice_head(n = 10) %>%
  ggplot(
    aes(
      reorder(state, highschool_2024),
      highschool_2024
    )
  ) +
  geom_col(fill = "steelblue") +
  coord_flip()

grad_chart <- bind_rows(
  top5_grad %>% mutate(group = "Top 5"),
  bottom5_grad %>% mutate(group = "Bottom 5")
)

ggplot(
  grad_chart,
  aes(
    reorder(state, highschool_2024),
    highschool_2024,
    fill = group
  )
) +
  geom_col() +
  coord_flip() +
  labs(
    title = "Top and Bottom 5 States by Graduation Rate (2024)",
    x = "State",
    y = "Graduation Rate (%)"
  )

Dataset 2: SAT Scores

The SAT dataset was also provided in a wide format where states were stored as columns and SAT measures were stored as rows. The dataset was transposed so that each state became an observation. The resulting dataset was then converted into a tidy format where SAT metrics and values were represented consistently.

library(readr)
SAT_score <- read_csv("https://raw.githubusercontent.com/lioneljr17/LDATA607/refs/heads/main/Project2/SAT_score.csv")
#View(SAT_score)
head(SAT_score)
# A tibble: 4 × 54
  State Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware
  <chr> <chr>   <chr>  <chr>   <chr>    <chr>      <chr>    <chr>       <chr>   
1 SAT … 3%      27%    10%     2%       26%        90%      91%         94%     
2 Tota… 1172    1097   1194    1177     1096       987      989         933     
3 Mean… 601     567    606     609      555        505      505         480     
4 Mean… 570     530    588     568      541        482      484         453     
# ℹ 45 more variables: `District of Columbia` <chr>, Florida <chr>,
#   Georgia <chr>, Hawaii <chr>, Idaho <chr>, Illinois <chr>, Indiana <chr>,
#   Iowa <chr>, Kansas <chr>, Kentucky <chr>, Louisiana <chr>, Maine <chr>,
#   Maryland <chr>, Massachusetts <chr>, Michigan <chr>, Minnesota <chr>,
#   Mississippi <chr>, Missouri <chr>, Montana <chr>, Nebraska <chr>,
#   Nevada <chr>, `New Hampshire` <chr>, `New Jersey` <chr>,
#   `New Mexico` <chr>, `New York` <chr>, `North Carolina` <chr>, …
sat_clean <- SAT_score %>%
  column_to_rownames("State") %>%
  t() %>%
  as.data.frame() %>%
  rownames_to_column("state")

names(sat_clean) <- c(
  "state",
  "participation_rate",
  "total_mean_score",
  "reading_score",
  "math_score"
)
head(sat_clean)
       state participation_rate total_mean_score reading_score math_score
1    Alabama                 3%             1172           601        570
2     Alaska                27%             1097           567        530
3    Arizona                10%             1194           606        588
4   Arkansas                 2%             1177           609        568
5 California                26%             1096           555        541
6   Colorado                90%              987           505        482
sat_clean <- sat_clean %>%
  mutate(
    participation_rate =
      as.numeric(gsub("%","",na_if(participation_rate,"N/A"))),
    total_mean_score =
      as.numeric(total_mean_score),
    reading_score =
      as.numeric(reading_score),
    math_score =
      as.numeric(math_score)
  )

sat_tidy <- sat_clean %>%
  pivot_longer(
    -state,
    names_to = "metric",
    values_to = "value"
  )
top5_sat <- sat_clean %>%
  arrange(desc(total_mean_score)) %>%
  slice_head(n = 5)

top5_sat
         state participation_rate total_mean_score reading_score math_score
1 North Dakota                  1             1254           631        623
2     Nebraska                  1             1249           630        619
3    Wisconsin                  2             1240           624        616
4       Kansas                  2             1238           626        612
5      Wyoming                  1             1234           638        597
bottom5_sat <- sat_clean %>%
  arrange(total_mean_score) %>%
  slice_head(n = 5)

sat_chart <- bind_rows(
  top5_sat %>% mutate(group = "Top 5"),
  bottom5_sat %>% mutate(group = "Bottom 5")
)
bottom5_sat
          state participation_rate total_mean_score reading_score math_score
1    New Mexico                100              875           451        424
2 West Virginia                 93              911           474        437
3      Delaware                 94              933           480        453
4  Rhode Island                 99              935           481        455
5       Indiana                100              950           485        464
sat_clean %>%
  arrange(desc(total_mean_score)) %>%
  slice_head(n = 10)
          state participation_rate total_mean_score reading_score math_score
1  North Dakota                  1             1254           631        623
2      Nebraska                  1             1249           630        619
3     Wisconsin                  2             1240           624        616
4        Kansas                  2             1238           626        612
5       Wyoming                  1             1234           638        597
6          Utah                  2             1229           622        606
7   Mississippi                  1             1223           624        598
8  South Dakota                  2             1214           619        595
9          Iowa                  2             1211           616        595
10    Minnesota                  3             1210           612        698
sat_clean %>%
  arrange(desc(total_mean_score)) %>%
  slice_head(n = 10) %>%
  ggplot(
    aes(
      reorder(state,total_mean_score),
      total_mean_score
    )
  ) +
  geom_col(fill = "darkgreen") +
  coord_flip()

ggplot(
  sat_chart,
  aes(
    reorder(state, total_mean_score),
    total_mean_score,
    fill = group
  )
) +
  geom_col() +
  coord_flip() +
  labs(
    title = "Top and Bottom 5 States by SAT Score",
    x = "State",
    y = "Average SAT Score"
  )

Dataset 3: School Funding 

The education funding dataset contained states as columns and funding categories as rows. Similar to the previous datasets, the data was transposed so that states became observations. The funding measures were then standardized and converted to numeric values after removing currency symbols.

library(readr)
states_school_funding <- read_csv("https://raw.githubusercontent.com/lioneljr17/LDATA607/refs/heads/main/Project2/states_school_funding.csv")
#View(states_school_funding)

head(states_school_funding)
# A tibble: 2 × 52
  State Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware
  <chr> <chr>   <chr>  <chr>   <chr>    <chr>      <chr>    <chr>       <chr>   
1 Tota… $2,866… $426.… $6,716… $1,467.… $19,701.13 $3,092.… $2,180.38   $503.58 
2 Dire… $1,526… $60.31 $3,844… $686.77  $8,854.55  $1,806.… $1,244.52   $248.95 
# ℹ 43 more variables: `District of Columbia` <chr>, Florida <chr>,
#   Georgia <chr>, Hawaii <chr>, Idaho <chr>, Illinois <chr>, Indiana <chr>,
#   Iowa <chr>, Kansas <chr>, Kentucky <chr>, Louisiana <chr>, Maine <chr>,
#   Maryland <chr>, Massachusetts <chr>, Michigan <chr>, Minnesota <chr>,
#   Mississippi <chr>, Missouri <chr>, Montana <chr>, Nebraska <chr>,
#   Nevada <chr>, `New Hampshire` <chr>, `New Jersey` <chr>,
#   `New Mexico` <chr>, `New York` <chr>, `North Carolina` <chr>, …
school_funding_clean <- states_school_funding %>%
  column_to_rownames("State") %>%
  t() %>%
  as.data.frame() %>%
  rownames_to_column("state")

names(school_funding_clean) <- c(
  "state",
  "total_budget",
  "direct_student_loans"
)

school_funding_clean <- school_funding_clean %>%
  mutate(
    total_budget =
      as.numeric(gsub("[$,]","",total_budget)),
    direct_student_loans =
      as.numeric(gsub("[$,]","",direct_student_loans))
  )

funding_tidy <- school_funding_clean %>%
  pivot_longer(
    -state,
    names_to = "funding_type",
    values_to = "amount"
  )
top5_funding <- school_funding_clean %>%
  arrange(desc(total_budget)) %>%
  slice_head(n = 5)
top5_funding
         state total_budget direct_student_loans
1   California     19701.13              8854.55
2        Texas     13509.50              5213.89
3     New York     12087.25              6463.10
4      Florida     10104.82              4836.90
5 Pennsylvania      7552.27              4698.04
bottom5_funding <- school_funding_clean %>%
  arrange(total_budget) %>%
  slice_head(n = 5)
bottom5_funding
         state total_budget direct_student_loans
1      Wyoming       281.36                77.06
2      Vermont       417.89               222.86
3       Alaska       426.36                60.31
4 North Dakota       451.90               202.73
5       Hawaii       500.48               193.92
funding_chart <- bind_rows(
  top5_funding %>% mutate(group = "Top 5"),
  bottom5_funding %>% mutate(group = "Bottom 5")
)
school_funding_clean %>%
  arrange(desc(total_budget)) %>%
  slice_head(n = 10)
          state total_budget direct_student_loans
1    California     19701.13              8854.55
2         Texas     13509.50              5213.89
3      New York     12087.25              6463.10
4       Florida     10104.82              4836.90
5  Pennsylvania      7552.27              4698.04
6      Illinois      7514.58              4036.74
7       Arizona      6716.04              3844.44
8          Ohio      5563.95              2898.07
9       Georgia      5405.03              2599.57
10     Virginia      4962.27              3022.01
school_funding_clean %>%
  arrange(desc(total_budget)) %>%
  slice_head(n = 10) %>%
  ggplot(
    aes(
      reorder(state,total_budget),
      total_budget
    )
  ) +
  geom_col(fill = "orange") +
  coord_flip()

ggplot(
  funding_chart,
  aes(
    reorder(state, total_budget),
    total_budget,
    fill = group
  )
) +
  geom_col() +
  coord_flip() +
  labs(
    title = "Top and Bottom 5 States by Education Funding",
    x = "State",
    y = "Funding (Millions)"
  )

Final Combined Analysis

combined_data <- grad_clean %>%
  select(
    state,
    highschool_2024
  ) %>%
  inner_join(
    sat_clean %>%
      select(
        state,
        total_mean_score
      ),
    by = "state"
  ) %>%
  inner_join(
    school_funding_clean %>%
      select(
        state,
        total_budget
      ),
    by = "state"
  )
combined_data %>%
  arrange(desc(total_mean_score))
                  state highschool_2024 total_mean_score total_budget
1          North Dakota            94.0             1254       451.90
2              Nebraska            92.2             1249      1160.46
3             Wisconsin            93.6             1240      2394.88
4                Kansas            92.0             1238      1452.06
5               Wyoming            94.2             1234       281.36
6                  Utah            93.4             1229      2728.52
7           Mississippi            87.1             1223      1693.30
8          South Dakota            93.2             1214       533.42
9                  Iowa            93.3             1211      1703.16
10            Minnesota            93.9             1210      3948.58
11              Montana            94.6             1205       505.06
12            Louisiana            87.3             1195      2914.63
13              Arizona            89.4             1194      6716.04
14            Tennessee            90.0             1189      3595.99
15             Kentucky            88.9             1181      2609.96
16             Arkansas            88.7             1177      1467.94
17               Nevada            87.5             1177      1001.79
18             Missouri            91.9             1174      3093.75
19              Alabama            88.6             1172      2866.48
20       North Carolina            90.1             1165      4720.18
21             Oklahoma            89.4             1150      2017.39
22               Oregon            91.8             1127      1855.19
23               Hawaii            93.2             1125       500.48
24              Vermont            94.9             1115       417.89
25        Massachusetts            91.4             1114      4107.66
26             Virginia            91.6             1112      4962.27
27               Alaska            93.6             1097       426.36
28           California            84.7             1096     19701.13
29           Washington            92.3             1095      2565.71
30         Pennsylvania            92.1             1084      7552.27
31                Maine            94.8             1078       737.69
32           New Jersey            90.7             1061      3817.12
33             New York            88.0             1045     12087.25
34              Georgia            89.2             1038      5405.03
35                 Ohio            91.8             1018      5563.95
36        New Hampshire            94.4             1017      1951.70
37       South Carolina            90.1             1017      2419.65
38                Idaho            91.9             1003       730.48
39             Maryland            91.1             1003      2708.83
40          Connecticut            91.5              989      2180.38
41             Colorado            92.9              987      3092.33
42              Florida            89.9              970     10104.82
43                Texas            86.0              964     13509.50
44             Illinois            90.5              961      7514.58
45 District of Columbia            92.7              958      1888.82
46             Michigan            92.1              953      4775.90
47              Indiana            90.4              950      3497.89
48         Rhode Island            89.7              935       746.06
49             Delaware            91.7              933       503.58
50        West Virginia            89.3              911      1110.80
51           New Mexico            88.0              875       933.79
  combined_data %>%
  select(
    highschool_2024,
    total_mean_score,
    total_budget
  ) %>%
  cor(
    use = "complete.obs"
  )
                 highschool_2024 total_mean_score total_budget
highschool_2024        1.0000000        0.1966690   -0.5515099
total_mean_score       0.1966690        1.0000000   -0.2010645
total_budget          -0.5515099       -0.2010645    1.0000000
ggplot(
  combined_data,
  aes(
    total_budget,
    total_mean_score
  )
) +
  geom_point(
    color = "darkgreen",
    size = 3
  ) +
  geom_smooth(
    method = "lm",
    se = FALSE,
    color = "black"
  ) +
  labs(
    title = "Education Funding vs SAT Scores",
    x = "Total Budget",
    y = "SAT Score"
  )

ggplot(
  combined_data,
  aes(
    total_budget,
    highschool_2024
  )
) +
  geom_point(
    color = "blue",
    size = 3
  ) +
  geom_smooth(
    method = "lm",
    se = FALSE
  ) +
  labs(
    title = "Education Funding vs Graduation Rate",
    x = "Total Budget",
    y = "Graduation Rate"
  )

ggplot(
  combined_data,
  aes(
    total_mean_score,
    highschool_2024
  )
) +
  geom_point(
    color = "red",
    size = 3
  ) +
  geom_smooth(
    method = "lm",
    se = FALSE
  ) +
  labs(
    title = "SAT Score vs Graduation Rate",
    x = "SAT Score",
    y = "Graduation Rate"
  )

combined_scaled <- combined_data %>%
  mutate(
    graduation_scaled =
      scale(highschool_2024)[,1],
    sat_scaled =
      scale(total_mean_score)[,1],
    funding_scaled =
      scale(total_budget)[,1]
  )


  combined_scaled_long <- combined_scaled %>%
  select(
    state,
    graduation_scaled,
    sat_scaled,
    funding_scaled
  ) %>%
  pivot_longer(
    -state,
    names_to = "metric",
    values_to = "value"
  )

  
  ggplot(
    combined_scaled_long,
    aes(
      state,
      value,
      fill = metric
    )
  ) +
  geom_col(position = "dodge") +
  theme(
    axis.text.x =
      element_text(
        angle = 90,
        hjust = 1
      )
  ) +
  labs(
    title = "Standardized Comparison of Graduation Rates, SAT Scores, and Education Funding",
    x = "State",
    y = "Standardized Value"
  )

After analyzing each dataset individually, the three datasets were combined to explore relationships among education funding, SAT performance, and graduation rates. Correlation analysis and visualizations suggest that states with higher educational investment often exhibit stronger educational outcomes. However, the relationship is not perfect, indicating that additional factors beyond funding contribute to student success. The combined analysis demonstrates how tidy datasets can be integrated to answer broader questions that would be difficult to investigate with a single dataset.

Conclusion

The independent analyses identified states with the highest graduation rates, SAT scores, and education funding levels. After combining the datasets, the results suggest that some relationship may exist between educational investment and academic outcomes. However, the strength of these relationships varies across states, suggesting that funding alone may not fully account for differences in graduation rates and SAT performance. Additional factors such as demographics, participation rates, and educational policies likely contribute to student outcomes.