This project analyzes the dataset “School Scores CSV File”. The SAT is a standardized test meant to test college applicants on Mathematics and Reading/Writing. It is used throughout universities in the United States. The dataset looks at the SAT scores among all American states from the years 2005 to 2015. It offers numerous variables to consider. This data was collected by Austin Cory Bart at Virginia Tech.
I chose this dataset due to my position as a university applicant for Fall 2027. Since the SAT is regarded as a significant aspect of college applications nationwide, I was curious to see what the indicators were for a high SAT score.
Variables
Total.Math: The average Math score of students in this state during this year. Quantitative.
Mathematics.Average.GPA: The average GPA of all students in this state during this year in Math. Note that this is just the GPA within the subject, not across all academic subjects. Quantitative.
English.Average.GPA: The average GPA of all students in this state during this year in English. Note that this is just the GPA within the subject, not across all academic subjects. Quantitative.
Foreign.Languages.Average.GPA: The average GPA of all students in this state during this year in Foreign Languages. Note that this is just the GPA within the subject, not across all academic subjects. Quantitative.
Natural.Sciences.Average.GPA: The average GPA of all students in this state during this year in the Natural Sciences. Note that this is just the GPA within the subject, not across all academic subjects.Quantitative.
Social.Sciences.History.Average.GPA: The average GPA of all students in this state during this year in Social Sciences and History. Note that this is just the GPA within the subject, not across all academic subjects. Quantitative.
Arts.Music.Average.GPA: The average GPA of all students in this state during this year in Arts/Music. Note that this is just the GPA within the subject, not across all academic subjects. Quantitative.
Year: The year of the report. Categorical.
State.Code: The two letter abbreviation of the state for the report. Categorical.
Since there were 99 variables, I had a lot of trouble narrowing down the variables I needed. I utilized a correlation plot to examine a couple variables. Many of the variables shared high correlation; I ended up focusing on the numerous school subjects and the GPA of each.
I cleaned up the dataset by substituting spaces for periods, substituting slashes for periods, and removing extraneous variable wording, all using gsub.
Research Question
What is the relationship between GPA and math SAT scores? Can GPA predict math SAT scores? Which subject GPA is the best predictor for math SAT score?
Loading libraries and dataset
#load librarieslibrary(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.2.1 ✔ readr 2.2.0
✔ forcats 1.0.1 ✔ stringr 1.6.0
✔ ggplot2 4.0.3 ✔ tibble 3.3.1
✔ lubridate 1.9.5 ✔ tidyr 1.3.2
✔ purrr 1.2.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Rows: 577 Columns: 99
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): State.Code, State.Name
dbl (97): Year, Total.Math, Total.Test-takers, Total.Verbal, Academic Subjec...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#substitute spaces for periodsnames(sat_data) <-gsub(" ",".",names(sat_data))#substitute / for periodsnames(sat_data) <-gsub("/", ".", names(sat_data))#get rid of "Academic.Subjects"names(sat_data) <-gsub("Academic.Subjects.", "", names(sat_data))head(sat_data)
# A tibble: 6 × 99
Year State.Code State.Name Total.Math `Total.Test-takers` Total.Verbal
<dbl> <chr> <chr> <dbl> <dbl> <dbl>
1 2005 AL Alabama 559 3985 567
2 2005 AK Alaska 519 3996 523
3 2005 AZ Arizona 530 18184 526
4 2005 AR Arkansas 552 1600 563
5 2005 CA California 522 186552 504
6 2005 CO Colorado 560 11990 560
# ℹ 93 more variables: Arts.Music.Average.GPA <dbl>,
# Arts.Music.Average.Years <dbl>, English.Average.GPA <dbl>,
# English.Average.Years <dbl>, Foreign.Languages.Average.GPA <dbl>,
# Foreign.Languages.Average.Years <dbl>, Mathematics.Average.GPA <dbl>,
# Mathematics.Average.Years <dbl>, Natural.Sciences.Average.GPA <dbl>,
# Natural.Sciences.Average.Years <dbl>,
# Social.Sciences.History.Average.GPA <dbl>, …
#keep data that would be further exploredsome_sat_data <- sat_data |>select(Total.Math, Total.Verbal, Mathematics.Average.GPA, English.Average.GPA, Foreign.Languages.Average.GPA, Natural.Sciences.Average.GPA, Arts.Music.Average.GPA, Natural.Sciences.Average.GPA, Social.Sciences.History.Average.GPA, Year, State.Code, Gender.Female.Math, Gender.Male.Math)head(some_sat_data)
#use correlation plot to explore correlation among the variableslibrary(DataExplorer)plot_correlation(some_sat_data)
Warning in dummify(data, maxcat = maxcat): Ignored all discrete features since
`maxcat` set to 20 categories!
#select the variables that should be usedsat_data2 <- sat_data |>select(Total.Math, Mathematics.Average.GPA, English.Average.GPA, Foreign.Languages.Average.GPA, Natural.Sciences.Average.GPA, Social.Sciences.History.Average.GPA, Arts.Music.Average.GPA, Year, State.Code)
Create ggplot
#create scatterplot for math GPA and math SATp1 <-ggplot(sat_data2, aes(x = Mathematics.Average.GPA, y = Total.Math)) +xlab("GPA in Math Subjects") +ylab("Math Score on Sat") +geom_point() +ggtitle("GPA in Math Subjects VS Math Score on SAT")p1
#add linear regression with confidence intervalp2 <- p1 +geom_smooth(method='lm',formula=y~x)p2
#create scatterplot for english GPA and math SATp3 <-ggplot(sat_data2, aes(x = English.Average.GPA, y = Mathematics.Average.GPA)) +xlab("GPA in English Subjects") +ylab("GPA in Math Subjects") +geom_point() +ggtitle("GPA in English Subjects VS GPA in Math Subjects") +geom_smooth(method='lm',formula=y~x)p3
#create scatterplot for reading GPA and math GPAp4 <-ggplot(sat_data2, aes(x = English.Average.GPA, y = Total.Math)) +xlab("GPA in English Subjects") +ylab("Math Score on Sat") +geom_point() +ggtitle("GPA in English Subjects VS Math Score on SAT") +geom_smooth(method='lm',formula=y~x)p4
Linear Regression
#check linear regression for math GPAlinear_math_sat <-lm(Total.Math ~ Mathematics.Average.GPA, data = sat_data2)summary(linear_math_sat)
Call:
lm(formula = Total.Math ~ Mathematics.Average.GPA, data = sat_data2)
Residuals:
Min 1Q Median 3Q Max
-122.167 -9.790 4.551 17.214 87.031
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -40.285 17.361 -2.32 0.0207 *
Mathematics.Average.GPA 173.992 5.233 33.25 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 27.03 on 575 degrees of freedom
Multiple R-squared: 0.6578, Adjusted R-squared: 0.6572
F-statistic: 1105 on 1 and 575 DF, p-value: < 2.2e-16
The adjusted r-squared is 0.6572 or 65.7%, which shows that the model explains 65.7% of the SAT scores.
The p-value on the right of math GPA has 3 asterisks, which shows that it is a highly significant variable to explain the linear increase in math SAT score.
The slope is 173.992. This means that with every one point increase in math GPA, the math SAT score rises by 174 points.
#create a multiple linear regression modellinear_sat <-lm(Total.Math ~ Mathematics.Average.GPA + English.Average.GPA + Foreign.Languages.Average.GPA + Natural.Sciences.Average.GPA + Arts.Music.Average.GPA + Social.Sciences.History.Average.GPA, data = sat_data2)summary(linear_sat)
The adjusted r-squared is 0.6927 or 69.3%, which shows that the model explains 69.3% of the SAT scores. This is a slight increase from only math GPA.
Math GPA: The p-value on the right of math GPA has 3 asterisks, which shows that it is a highly significant variable to explain the linear increase in math SAT score. The slope is 115.43. This means that with every one point increase in math GPA, the math SAT score rises by 115 points.
English GPA: The p-value on the right of english GPA has 2 asterisks, which shows that it is a significant variable to explain the linear increase in math SAT score. The slope is -116.64. This means that with every one point increase in english GPA, the math SAT score falls by 117 points.
Foreign Languages GPA: The p-value on the right of foreign languages GPA has 2 asterisks, which shows that it is a significant variable to explain the linear increase in math SAT score. The slope is -69.67. This means that with every one point increase in foreign languages GPA, the math SAT score falls by 70 points.
Natural Sciences GPA: The p-value on the right of natural sciences GPA has 0 asterisks, which shows that it is not a significant variable to explain the linear increase in math SAT score. The slope is 33.04. This means that with every one point increase in natural sciences GPA, the math SAT score rises by 33 points.
Arts and Music GPA: The p-value on the right of arts and music GPA has 1 asterisk, which shows that it is a less significant variable to explain the linear increase in math SAT score. The slope is 71.82. This means that with every one point increase in arts and music GPA, the math SAT score rises by 72 points.
Social Sciences GPA: The p-value on the right of social sciences GPA has 3 asterisks, which shows that it is a highly significant variable to explain the linear increase in math SAT score. The slope is 197.58. This means that with every one point increase in math GPA, the math SAT score rises by 198 points.
The math GPA is the most statistically significant relationship with math SAT scores.
Yes, GPA in many subjects is able to predict math SAT scoring. The math GPA, as expected, is the best predictor with Social Sciences GPA being the second-best. The least significant variable is Natural Sciences GPA.
Plotly Graph
#load required packageslibrary(plotly)
Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':
last_plot
The following object is masked from 'package:stats':
filter
The following object is masked from 'package:graphics':
layout
The visualization shows the correlation between GPA in math Subjects and math score on the SAT. The relationship can be seen for specific states, with some exhibiting interesting behavior. For example, the regression line for Puerto Rico and District of Columbia seems to be negative, while most other states positive. Additionally, District of Columbia stands out as as a state with lower GPA and math score.
I struggled with finding a custom color palette with enough colors for all states. I also struggled with making the regression lines thinner and less opaque without provoking a glitch in the graph. I would have wanted to also allow the year to show up when hovering over a data point.
#add the Region column to your existing sat_datasat_data$Region <- region_map[sat_data$State.Code]
#generate the scatter plot colored by the manual Region columnggplot(sat_data, aes(x =`Total.Test-takers`, y = Total.Math, color = Region)) +geom_point(size =4) +labs(title ="Math Scores vs. Total Test-Takers by Region (2005)",x ="Total Test-Takers",y ="Total Math Score",color ="US Region" ) +theme_minimal()
Bibliography
CN, P., Kouchi, B., & Kurup, M. (2026, June 9). How to use sub() and GSUB() in R | DigitalOcean. Www.Digitalocean.Com. https://www.digitalocean.com/community/tutorials/sub-and-gsub-function-r
Keita, Z. (2022, December 6). Multiple linear regression in R: Tutorial with examples. DataCamp. Datacamp.Com. https://www.datacamp.com/tutorial/multiple-linear-regression-r-tutorial
Multiple linear regression in R: LM() & interpretation. (2026, June 23). Datanovia. https://www.datanovia.com/learn/biostatistics/regression/multiple-linear-regression-in-r