Given the fictional academic data set concerning 50 CS students across 5 quarters, we can ask several questions:
Using this data set as a sample population of CS students, we can attempt to answer these questions.
To process the data, I first made a copy of the provided Google Sheets data. I then added a year and quarter column for each Timestamp column to indicate the year (e.g. 2024) and the quarter (e.g. FQ). I added a new column for each quarter to show if the student took a leave of absence prior to starting the current quarter (we do not know if students took a leave before the first quarter, Q1, but we do know for the following four quarters).
After formatting the data in this way, I downloaded the edited sheet as a csv file and imported the file into RStudio to answer some of the questions presented above.
The given data set includes both CS GPA as well as overall GPA, so we can create two separate graphs to show how they differ. The naive approach would be to take the average GPA of all the students for each quarter and plot the GPA values on a scatter plot or bar graph to show the correlation between time and GPA, but there may be variance hidden within the averages. In order to account for the variance in student performance, we can use box plots across multiple quarters to show the standard deviation per quarter.
# organize graph framing
par(mfrow=c(1,2), mai = c(1,1,0.5,0.5))
## Overall GPA
# Load data
library(readr)
main_student_records <- read_csv("~/LupLab Screening Test/test_student_records.csv",
col_types = cols(Q1_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q2_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q3_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q4_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q5_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ"))))
# Create a data frame for each quarter using each "Overall_GPA" column
Q1_overall_gpa <- data.frame(main_student_records$Q1_Overall_GPA)
Q2_overall_gpa <- data.frame(main_student_records$Q2_Overall_GPA)
Q3_overall_gpa <- data.frame(main_student_records$Q3_Overall_GPA)
Q4_overall_gpa <- data.frame(main_student_records$Q4_Overall_GPA)
Q5_overall_gpa <- data.frame(main_student_records$Q5_Overall_GPA)
# Combine the quarter GPA columns into one data set
overall_gpa <- data.frame(Q1_overall_gpa, Q2_overall_gpa, Q3_overall_gpa, Q4_overall_gpa, Q5_overall_gpa)
# Format table for box plot
overall_gpa_table <- data.frame(matrix(NA, nrow=250, ncol=2))
for (i in 1:50) {
overall_gpa_table[i,1] <- overall_gpa[i,1]
overall_gpa_table[i,2] <- "Q1"
}
for (i in 1:50) {
overall_gpa_table[i+50,1] <- overall_gpa[i,2]
overall_gpa_table[i+50,2] <- "Q2"
}
for (i in 1:50) {
overall_gpa_table[i+100,1] <- overall_gpa[i,3]
overall_gpa_table[i+100,2] <- "Q3"
}
for (i in 1:50) {
overall_gpa_table[i+150,1] <- overall_gpa[i,4]
overall_gpa_table[i+150,2] <- "Q4"
}
for (i in 1:50) {
overall_gpa_table[i+200,1] <- overall_gpa[i,5]
overall_gpa_table[i+200,2] <- "Q5"
}
# Rename columns in main table
colnames(overall_gpa_table) <- c("Overall_GPA", "Quarter")
# Convert Quarter column from string to factor variables
overall_gpa_table$Quarter <- as.factor(overall_gpa_table$Quarter)
# Create box plot
plot(overall_gpa_table$Overall_GPA ~ overall_gpa_table$Quarter,
data = overall_gpa_table,
ylab = "Overall GPA",
xlab = "Quarter",
ylim = c(1,5),
col = "lightgreen",
whisklty = 3,
whisklwd = 2,
staplelwd = 2,
main = "Overall GPA over Time")
box("outer", col="darkgreen", lwd = 3)
# Add overlaying average lines
overall_gpa_averages <- data.frame(x=c(overall_gpa_table$Quarter[1],
overall_gpa_table$Quarter[51],
overall_gpa_table$Quarter[101],
overall_gpa_table$Quarter[151],
overall_gpa_table$Quarter[201]),
y=c(mean(main_student_records$Q1_Overall_GPA),
mean(main_student_records$Q2_Overall_GPA),
mean(main_student_records$Q3_Overall_GPA),
mean(main_student_records$Q4_Overall_GPA),
mean(main_student_records$Q5_Overall_GPA)))
points(overall_gpa_averages$x, overall_gpa_averages$y, col = "red", pch=16)
## CS GPA
# Load data
library(readr)
main_student_records <- read_csv("~/LupLab Screening Test/test_student_records.csv",
col_types = cols(Q1_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q2_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q3_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q4_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q5_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ"))))
# Create a data frame for each quarter using each "CS_GPA" column
Q1_cs_gpa <- data.frame(main_student_records$Q1_CS_GPA)
Q2_cs_gpa <- data.frame(main_student_records$Q2_CS_GPA)
Q3_cs_gpa <- data.frame(main_student_records$Q3_CS_GPA)
Q4_cs_gpa <- data.frame(main_student_records$Q4_CS_GPA)
Q5_cs_gpa <- data.frame(main_student_records$Q5_CS_GPA)
# Combine the quarter GPA columns into one data set
cs_gpa <- data.frame(Q1_cs_gpa, Q2_cs_gpa, Q3_cs_gpa, Q4_cs_gpa, Q5_cs_gpa)
# Format table for box plot
cs_gpa_table <- data.frame(matrix(NA, nrow=250, ncol=2))
for (i in 1:50) {
cs_gpa_table[i,1] <- cs_gpa[i,1]
cs_gpa_table[i,2] <- "Q1"
}
for (i in 1:50) {
cs_gpa_table[i+50,1] <- cs_gpa[i,2]
cs_gpa_table[i+50,2] <- "Q2"
}
for (i in 1:50) {
cs_gpa_table[i+100,1] <- cs_gpa[i,3]
cs_gpa_table[i+100,2] <- "Q3"
}
for (i in 1:50) {
cs_gpa_table[i+150,1] <- cs_gpa[i,4]
cs_gpa_table[i+150,2] <- "Q4"
}
for (i in 1:50) {
cs_gpa_table[i+200,1] <- cs_gpa[i,5]
cs_gpa_table[i+200,2] <- "Q5"
}
# Rename columns in main table
colnames(cs_gpa_table) <- c("CS_GPA", "Quarter")
# Convert Quarter column from string to factor variables
cs_gpa_table$Quarter <- as.factor(cs_gpa_table$Quarter)
# Create box plot
plot(cs_gpa_table$CS_GPA ~ cs_gpa_table$Quarter,
data = cs_gpa_table,
ylab = "CS GPA",
xlab = "Quarter",
ylim = c(1,5),
col = "lightblue",
whisklty = 3,
whisklwd = 2,
staplelwd = 2,
main = "CS GPA over Time")
# Add overlaying average lines
cs_gpa_averages <- data.frame(x=c(cs_gpa_table$Quarter[1],
cs_gpa_table$Quarter[51],
cs_gpa_table$Quarter[101],
cs_gpa_table$Quarter[151],
cs_gpa_table$Quarter[201]),
y=c(mean(main_student_records$Q1_CS_GPA),
mean(main_student_records$Q2_CS_GPA),
mean(main_student_records$Q3_CS_GPA),
mean(main_student_records$Q4_CS_GPA),
mean(main_student_records$Q5_CS_GPA)))
points(cs_gpa_averages$x, cs_gpa_averages$y, col = "red", pch=16)
For both CS GPA and Overall GPA plots, we see that the average
GPA (the points in red) all hover around 3 and increase in tiny
increments over time, but the amount of variance differs, particularly
during Quarter 2 (Q2) and Quarter 3 (Q3).
There is a much wider range of overall GPA scores, both higher and lower, in Q2 compared to Q1. While the range decreases a minor amount in Q3, there still remains a larger range compared to Q1. This shows that some students are performing worse in their second quarter, while others are performing better compared to Q1. The trend continues in a less exaggerated fashion in Q3.
One possible reason for this trend is that in Q2, students may be taking on courses of differing difficulties from their Q1 classes, resulting in changing their GPA somewhat drastically (as well as their decreased average overall Q2 GPA). Then in Q3, students may use their experiences during Q1 and Q2 to inform their choices of classes depending on the difficulty they believe they are able to handle, resulting in the tighter grouping of GPA scores (as well as the increased GPA from Q2). As time goes on, the range of GPA scores shrinks and even increases as a whole, as seen during Q5.
Another possible factor affecting GPA scores to change over time is the fact that students respond to learning difficulties differently. Some students may use various methods to study more effectively, while others may become overwhelmed with more difficult classes in later quarters and require time to build their confidence and healthy study and learning habits in order to raise their GPA. Some students may quickly become academically proficient by learning from their experiences in Q1, resulting in the increased GPA maximums in Q2 through Q5 compared to Q1. Others might not endure more difficult classes as well, resulting in the decreased GPA minimums in Q2 and Q3. In the end most students end up increasing their GPA scores as evidenced by the increased Q5 minimum and maximum GPA scores, and the increased Q5 GPA average. This indicates that many students eventually figure out methods of learning that best suit themselves by the fifth quarter.
Looking at the CS GPA graph, there is a similar pattern to the overall GPA graph, with the difference being the GPA maximum scores generally staying the same over time, and the lowest GPA minimum score being in Q3 rather than Q2.
One explanation for the stability of the maximum GPA is because there may not many extra credit opportunities to earn a GPA above 4.0 in CS classes compared to classes overall. In this way, there is an artificial GPA limit of 4.0 in CS courses.
We also see that there are difficulties in earning a higher GPA in Q3 for CS classes compared to overall classes in Q2 and Q3. There is a minimum GPA score of about 1.75 in Q3, while the next lowest minimum GPA score is around 2 in Q2, where the other quarters’ minimum scores are. This suggests that there are either more difficult subjects taught in Q3 CS classes (meaning that the difficulty increase in classes occurs later in CS classes compared to other classes), students encounter learning difficulties in later quarter classes, or a combination of the two factors.
We see a similar upward trend in GPA scores in the latter half of the
studied time period, where the minimum GPA score, average GPA, and
median GPA increases in Q4 and Q5. This aligns with the previous
conclusion of overall classes that most students eventually become
academically proficient over time.
We can create a series of bar graphs to show the relationship between the number of units taken and the average GPA earned for those units. We can also see how the impact of number of units on GPA changes for overall GPA and just CS GPA using the average GPA across all quarters.
# Load data and libraries
library(readr)
library(dplyr)
library(ggplot2)
library(hrbrthemes)
library(gridExtra)
main_student_records <- read_csv("~/LupLab Screening Test/test_student_records.csv",
col_types = cols(Q1_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q2_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q3_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q4_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q5_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ"))))
## Overall GPA
# Create a data frame for each quarter using each "Overall_GPA" and "Total_Units " columns
Q1_overall_gpa <- data.frame(main_student_records$Q1_Overall_GPA)
Q2_overall_gpa <- data.frame(main_student_records$Q2_Overall_GPA)
Q3_overall_gpa <- data.frame(main_student_records$Q3_Overall_GPA)
Q4_overall_gpa <- data.frame(main_student_records$Q4_Overall_GPA)
Q5_overall_gpa <- data.frame(main_student_records$Q5_Overall_GPA)
# Combine the quarter GPA columns into one data set
overall_gpa <- data.frame(main_student_records$Q1_Overall_GPA,
main_student_records$Q2_Overall_GPA,
main_student_records$Q3_Overall_GPA,
main_student_records$Q4_Overall_GPA,
main_student_records$Q5_Overall_GPA,
main_student_records$Q1_Total_Units,
main_student_records$Q2_Total_Units,
main_student_records$Q3_Total_Units,
main_student_records$Q4_Total_Units,
main_student_records$Q5_Total_Units)
# Create empty data frame for 2x250 table frame and rename columns
overall_gpa_and_units <- data.frame(matrix(NA, nrow=250, ncol=2))
colnames(overall_gpa_and_units) <- c("overall_gpa", "units")
# Fill data frame with overall GPA and units
for (i in 1:50) {
overall_gpa_and_units[i,1] <- overall_gpa[i,1]
overall_gpa_and_units[i,2] <- overall_gpa[i,6]
}
for (i in 1:50) {
overall_gpa_and_units[i+50,1] <- overall_gpa[i,2]
overall_gpa_and_units[i+50,2] <- overall_gpa[i,7]
}
for (i in 1:50) {
overall_gpa_and_units[i+100,1] <- overall_gpa[i,3]
overall_gpa_and_units[i+100,2] <- overall_gpa[i,8]
}
for (i in 1:50) {
overall_gpa_and_units[i+150,1] <- overall_gpa[i,4]
overall_gpa_and_units[i+150,2] <- overall_gpa[i,9]
}
for (i in 1:50) {
overall_gpa_and_units[i+200,1] <- overall_gpa[i,5]
overall_gpa_and_units[i+200,2] <- overall_gpa[i,10]
}
# use overall_gpa_and_units %>% count(units) to count occurences of taking x # of units
unit_occurrences <- c(7,9,17,17,32,33,24,27,31,23,13,11,6)
# Get averages for each number of units taken
# Range of units is 8-20, so find average of all overall GPA values with the same units and put them in frame
avg_overall_gpa_with_units <- data.frame(matrix(NA, nrow=13, ncol=3))
for (i in 8:20) {
avg_overall_gpa_with_units[i-7,1] <-
mean(overall_gpa_and_units[overall_gpa_and_units$units == i, 'overall_gpa'])
avg_overall_gpa_with_units[i-7,2] <- i
avg_overall_gpa_with_units[i-7,3] <- unit_occurrences[i-7]
}
# rename columns
colnames(avg_overall_gpa_with_units) <- c("avg_overall_gpa", "units", "Occurrences")
# Convert units column from integer to factor variables
avg_overall_gpa_with_units$units <- as.factor(avg_overall_gpa_with_units$units)
# Calculate positions on the x axis for each bar (left border, central position, right border)
avg_overall_gpa_with_units$right <-
cumsum(avg_overall_gpa_with_units$Occurrences) +
30*c(0:(nrow(avg_overall_gpa_with_units)-1))
avg_overall_gpa_with_units$left <-
avg_overall_gpa_with_units$right - avg_overall_gpa_with_units$Occurrences
# plot graph: Average GPA as a function of units taken
ggplot(avg_overall_gpa_with_units, aes(x = units, y = avg_overall_gpa, ymin = 0)) +
xlab("Units Taken") +
ylab("Average Overall GPA") +
ylim(c(2,4)) +
labs(title="Average Overall GPA vs Units Taken across All Quarters") +
geom_point(aes(size = Occurrences)) +
theme(panel.grid.major.y = element_line(color = "black",
linewidth = 1,
linetype = 1)) +
theme(panel.grid.minor.y = element_line(color = "lightgrey",
linewidth = 0.75,
linetype = 1)) +
theme(panel.grid.major.x = element_line(color = "black",
linewidth = 0.5,
linetype = 1)) +
theme(plot.background = element_rect(color = "darkblue",
linewidth = 1.5))
## CS GPA
# Create a data frame for each quarter using each "CS_GPA" and "Total_Units " columns
Q1_cs_gpa <- data.frame(main_student_records$Q1_CS_GPA)
Q2_cs_gpa <- data.frame(main_student_records$Q2_CS_GPA)
Q3_cs_gpa <- data.frame(main_student_records$Q3_CS_GPA)
Q4_cs_gpa <- data.frame(main_student_records$Q4_CS_GPA)
Q5_cs_gpa <- data.frame(main_student_records$Q5_CS_GPA)
# Combine the quarter GPA columns into one data set
cs_gpa <- data.frame(main_student_records$Q1_CS_GPA,
main_student_records$Q2_CS_GPA,
main_student_records$Q3_CS_GPA,
main_student_records$Q4_CS_GPA,
main_student_records$Q5_CS_GPA,
main_student_records$Q1_Total_Units,
main_student_records$Q2_Total_Units,
main_student_records$Q3_Total_Units,
main_student_records$Q4_Total_Units,
main_student_records$Q5_Total_Units)
# Create empty data frame for 2x250 table frame and rename columns
cs_gpa_and_units <- data.frame(matrix(NA, nrow=250, ncol=2))
colnames(cs_gpa_and_units) <- c("cs_gpa", "units")
# Fill data frame with cs GPA and units
for (i in 1:50) {
cs_gpa_and_units[i,1] <- cs_gpa[i,1]
cs_gpa_and_units[i,2] <- cs_gpa[i,6]
}
for (i in 1:50) {
cs_gpa_and_units[i+50,1] <- cs_gpa[i,2]
cs_gpa_and_units[i+50,2] <- cs_gpa[i,7]
}
for (i in 1:50) {
cs_gpa_and_units[i+100,1] <- cs_gpa[i,3]
cs_gpa_and_units[i+100,2] <- cs_gpa[i,8]
}
for (i in 1:50) {
cs_gpa_and_units[i+150,1] <- cs_gpa[i,4]
cs_gpa_and_units[i+150,2] <- cs_gpa[i,9]
}
for (i in 1:50) {
cs_gpa_and_units[i+200,1] <- cs_gpa[i,5]
cs_gpa_and_units[i+200,2] <- cs_gpa[i,10]
}
# use cs_gpa_and_units %>% count(units) to count occurences of taking x # of units
unit_occurrences <- c(7,9,17,17,32,33,24,27,31,23,13,11,6)
# Get averages for each number of units taken
# Range of units is 8-20, so find average of all cs GPA values with the same units and put them in frame
avg_cs_gpa_with_units <- data.frame(matrix(NA, nrow=13, ncol=3))
for (i in 8:20) {
avg_cs_gpa_with_units[i-7,1] <-
mean(cs_gpa_and_units[cs_gpa_and_units$units == i, 'cs_gpa'])
avg_cs_gpa_with_units[i-7,2] <- i
avg_cs_gpa_with_units[i-7,3] <- unit_occurrences[i-7]
}
# rename columns
colnames(avg_cs_gpa_with_units) <- c("avg_cs_gpa", "units", "Occurrences")
# Convert units column from integer to factor variables
avg_cs_gpa_with_units$units <- as.factor(avg_cs_gpa_with_units$units)
# Calculate positions on the x axis for each bar (left border, central position, right border)
avg_cs_gpa_with_units$right <-
cumsum(avg_cs_gpa_with_units$Occurrences) +
30*c(0:(nrow(avg_cs_gpa_with_units)-1))
avg_cs_gpa_with_units$left <-
avg_cs_gpa_with_units$right - avg_cs_gpa_with_units$Occurrences
# plot graph: Average GPA as a function of units taken
ggplot(avg_cs_gpa_with_units, aes(x = units, y = avg_cs_gpa, ymin = 0)) +
xlab("Units Taken") +
ylab("Average CS GPA") +
ylim(c(2,4)) +
labs(title="Average CS GPA vs Units Taken across All Quarters") +
geom_point(aes(size = Occurrences)) +
theme(panel.grid.major.y = element_line(color = "black",
linewidth = 1,
linetype = 1)) +
theme(panel.grid.minor.y = element_line(color = "lightgrey",
linewidth = 0.75,
linetype = 1)) +
theme(panel.grid.major.x = element_line(color = "black",
linewidth = 0.5,
linetype = 1)) +
theme(plot.background = element_rect(color = "darkblue",
linewidth = 1.5))
One difference between the CS GPA graph and the Overall GPA
graph is that the average GPA scores in the CS graph are lower than the
corresponding average GPA scores in the Overall GPA graph. This can be
explained by an observation made in the previous question (How do CS
students generally perform over time?) in which there was a maximum
recorded GPA of 4.0 in the box plots of CS GPA scores while there were
higher maximum recorded GPA scores in the box plots of Overall GPA
scores most likely due to fewer extra credit opportunities in CS
classes.
Both graphs show the same interesting GPA pattern, as the average GPA (for both overall and cs graphs) decreases from approximately 3.25 to 2.75 when the units taken increases from 8 to 11 units. When the number of units taken is 12, the average GPA jumps back up to about 3.2 and steadily decreases to 2.75 as the units increase to 17 units. Finally, when the number of units taken is 18, the average GPA jumps back up to about 3.2 and decreases down to a little less than 2.75 as the units increase to 20 units.
Additionally, the size of the points indicates the number of times that students enrolling in the given number of units occur in the data set. Since the points are largest in the 12-17 units range and smallest in the extremes, we can conclude that the majority of students enroll in 12-17 units.
This pattern is the same for both graphs, which suggests that there are at least three different groups of students who enroll with three unit ranges: 8-11, 12-17, and 18-20. It is important to take into account the fact that full time college enrollment in the Unites States is the equivalent of 12 units, and federal financial aid requires full time enrollment for a student to have maximum eligibility. This suggests that many students enroll with the minimum amount of units possible in order to maintain eligibility for financial aid, while at the same time refraining from taking too many units such that they would not be able to keep up with the academic workload.
I expected that GPA would decrease as the number of units taken since academic workload increases and students encounter difficulties in keeping up with the workload, while GPA would increase at the highest units taken because of the assumption that most students taking 18-20 units would be aware of their academic ability and are proficient enough to maintain a higher GPA under such a massively increased academic workload.
This expectation is supported by the evidence in the two graphs
above, since the points from 12-17 units are larger than the points on
the low and high unit extremes, and GPA decreases as units increase
within that range - as well as within the other two distinct ranges of
8-11 units and 18-20 units.
I predict that leaves of absence will have a negative effect on GPA because time not spent reinforcing concepts will cause students to forget information. In order to answer this question, we can compare the change in average GPA across 2 quarters for students who take a leave before a quarter with the average GPA of students who have been enrolled in the previous quarter. We will focus on average overall GPA because non-CS classes also require academic skills such as effective study habits which can deteriorate over time if they are not used. The graphs below show the differences in how the average overall GPA changes from quarter to quarter when students take leaves of absence as compared to when students are enrolled in consecutive quarters.
## Average overall GPA of students who take leaves of absence vs Average overall GPA of students who enroll in consecutive quarters, per quarter
# Load data
library(readr)
library(ggplot2)
main_student_records <- read_csv("~/LupLab Screening Test/test_student_records.csv",
col_types = cols(Q1_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q2_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q3_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q4_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ")), Q5_Time_Quarter = col_factor(levels = c("FQ",
"WQ", "SQ"))))
################################################################################
## Q1-Q2: Create data frames to compare Q2 to Q1 Overall GPA ()
Q1_to_Q2_Absent <- data.frame(Absent_Q1_GPA=double(),
Absent_Q2_GPA=double(),
stringsAsFactors=FALSE)
Q1_to_Q2_Consecutive <- data.frame(Consecutive_Q1_GPA=double(),
Consecutive_Q2_GPA=double(),
stringsAsFactors=FALSE)
# Run through Pre_Q2_Absence column and for each student, if they took a break (value is TRUE), add row containing values from Q2_Overall_GPA and Q1_Overall_GPA to new data frame
for (i in 1:50) {
if (main_student_records$Pre_Q2_Absence[i] == TRUE) {
Q1_to_Q2_Absent[nrow(Q1_to_Q2_Absent)+1,] =
c(main_student_records$Q1_Overall_GPA[i],
main_student_records$Q2_Overall_GPA[i])
}
else if (main_student_records$Pre_Q2_Absence[i] == FALSE) {
Q1_to_Q2_Consecutive[nrow(Q1_to_Q2_Consecutive)+1,] =
c(main_student_records$Q1_Overall_GPA[i],
main_student_records$Q2_Overall_GPA[i])
}
else {
stop("reached non-logical value")
}
}
# Find difference in GPA from Q1 and Q2 for both data frames as a new column in both
Q1_to_Q2_Absent$Absent_GPA_Difference <- (Q1_to_Q2_Absent$Absent_Q2_GPA -
Q1_to_Q2_Absent$Absent_Q1_GPA)
Q1_to_Q2_Consecutive$Consecutive_GPA_Difference <-
(Q1_to_Q2_Consecutive$Consecutive_Q2_GPA -
Q1_to_Q2_Consecutive$Consecutive_Q1_GPA)
# Find average of GPA differences and put into list (to put in final plot w/ all quarters)
Q1_to_Q2 <- c(mean(Q1_to_Q2_Absent$Absent_GPA_Difference),
mean(Q1_to_Q2_Consecutive$Consecutive_GPA_Difference))
################################################################################
## Q2-Q3: Create data frames to compare Q3 to Q2 Overall GPA ()
Q2_to_Q3_Absent <- data.frame(Absent_Q2_GPA=double(),
Absent_Q3_GPA=double(),
stringsAsFactors=FALSE)
Q2_to_Q3_Consecutive <- data.frame(Consecutive_Q2_GPA=double(),
Consecutive_Q3_GPA=double(),
stringsAsFactors=FALSE)
# Run through Pre_Q3_Absence column and for each student, if they took a break (value is TRUE), add row containing values from Q3_Overall_GPA and Q2_Overall_GPA to new data frame
for (i in 1:50) {
if (main_student_records$Pre_Q3_Absence[i] == TRUE) {
Q2_to_Q3_Absent[nrow(Q2_to_Q3_Absent)+1,] =
c(main_student_records$Q2_Overall_GPA[i],
main_student_records$Q3_Overall_GPA[i])
}
else if (main_student_records$Pre_Q3_Absence[i] == FALSE) {
Q2_to_Q3_Consecutive[nrow(Q2_to_Q3_Consecutive)+1,] =
c(main_student_records$Q2_Overall_GPA[i],
main_student_records$Q3_Overall_GPA[i])
}
else {
stop("reached non-logical value")
}
}
# Find difference in GPA from Q2 and Q3 for both data frames as a new column in both
Q2_to_Q3_Absent$Absent_GPA_Difference <- (Q2_to_Q3_Absent$Absent_Q3_GPA -
Q2_to_Q3_Absent$Absent_Q2_GPA)
Q2_to_Q3_Consecutive$Consecutive_GPA_Difference <-
(Q2_to_Q3_Consecutive$Consecutive_Q3_GPA -
Q2_to_Q3_Consecutive$Consecutive_Q2_GPA)
# Find average of GPA differences and put into list (to put in final plot w/ all quarters)
Q2_to_Q3 <- c(mean(Q2_to_Q3_Absent$Absent_GPA_Difference),
mean(Q2_to_Q3_Consecutive$Consecutive_GPA_Difference))
################################################################################
## Q3-Q4: Create data frames to compare Q4 to Q3 Overall GPA ()
Q3_to_Q4_Absent <- data.frame(Absent_Q3_GPA=double(),
Absent_Q4_GPA=double(),
stringsAsFactors=FALSE)
Q3_to_Q4_Consecutive <- data.frame(Consecutive_Q3_GPA=double(),
Consecutive_Q4_GPA=double(),
stringsAsFactors=FALSE)
# Run through Pre_Q4_Absence column and for each student, if they took a break (value is TRUE), add row containing values from Q4_Overall_GPA and Q3_Overall_GPA to new data frame
for (i in 1:50) {
if (main_student_records$Pre_Q4_Absence[i] == TRUE) {
Q3_to_Q4_Absent[nrow(Q3_to_Q4_Absent)+1,] =
c(main_student_records$Q3_Overall_GPA[i],
main_student_records$Q4_Overall_GPA[i])
}
else if (main_student_records$Pre_Q4_Absence[i] == FALSE) {
Q3_to_Q4_Consecutive[nrow(Q3_to_Q4_Consecutive)+1,] =
c(main_student_records$Q3_Overall_GPA[i],
main_student_records$Q4_Overall_GPA[i])
}
else {
stop("reached non-logical value")
}
}
# Find difference in GPA from Q3 and Q4 for both data frames as a new column in both
Q3_to_Q4_Absent$Absent_GPA_Difference <- (Q3_to_Q4_Absent$Absent_Q4_GPA -
Q3_to_Q4_Absent$Absent_Q3_GPA)
Q3_to_Q4_Consecutive$Consecutive_GPA_Difference <-
(Q3_to_Q4_Consecutive$Consecutive_Q4_GPA -
Q3_to_Q4_Consecutive$Consecutive_Q3_GPA)
# Find average of GPA differences and put into list (to put in final plot w/ all quarters)
Q3_to_Q4 <- c(mean(Q3_to_Q4_Absent$Absent_GPA_Difference),
mean(Q3_to_Q4_Consecutive$Consecutive_GPA_Difference))
################################################################################
## Q4-Q5: Create data frames to compare Q5 to Q4 Overall GPA ()
Q4_to_Q5_Absent <- data.frame(Absent_Q4_GPA=double(),
Absent_Q5_GPA=double(),
stringsAsFactors=FALSE)
Q4_to_Q5_Consecutive <- data.frame(Consecutive_Q4_GPA=double(),
Consecutive_Q5_GPA=double(),
stringsAsFactors=FALSE)
# Run through Pre_Q5_Absence column and for each student, if they took a break (value is TRUE), add row containing values from Q5_Overall_GPA and Q4_Overall_GPA to new data frame
for (i in 1:50) {
if (main_student_records$Pre_Q5_Absence[i] == TRUE) {
Q4_to_Q5_Absent[nrow(Q4_to_Q5_Absent)+1,] =
c(main_student_records$Q4_Overall_GPA[i],
main_student_records$Q5_Overall_GPA[i])
}
else if (main_student_records$Pre_Q5_Absence[i] == FALSE) {
Q4_to_Q5_Consecutive[nrow(Q4_to_Q5_Consecutive)+1,] =
c(main_student_records$Q4_Overall_GPA[i],
main_student_records$Q5_Overall_GPA[i])
}
else {
stop("reached non-logical value")
}
}
# Find difference in GPA from Q3 and Q4 for both data frames as a new column in both
Q4_to_Q5_Absent$Absent_GPA_Difference <- (Q4_to_Q5_Absent$Absent_Q5_GPA -
Q4_to_Q5_Absent$Absent_Q4_GPA)
Q4_to_Q5_Consecutive$Consecutive_GPA_Difference <-
(Q4_to_Q5_Consecutive$Consecutive_Q5_GPA -
Q4_to_Q5_Consecutive$Consecutive_Q4_GPA)
# Find average of GPA differences and put into list (to put in final plot w/ all quarters)
Q4_to_Q5 <- c(mean(Q4_to_Q5_Absent$Absent_GPA_Difference),
mean(Q4_to_Q5_Consecutive$Consecutive_GPA_Difference))
################################################################################
# combine quarters
combined_quarters <- data.frame(quarter_one = c(Q1_to_Q2[1],
Q2_to_Q3[1],
Q3_to_Q4[1],
Q4_to_Q5[1]),
quarter_two = c(Q1_to_Q2[2],
Q2_to_Q3[2],
Q3_to_Q4[2],
Q4_to_Q5[2]))
# average change in gpa
avg_quarter_diff <- c(mean(combined_quarters$quarter_one),
mean(combined_quarters$quarter_two))
################################################################################
## create data frame for each quarter for grouped bar graph
GPA_Differences <- data.frame(quarter=c("Q1 to Q2",
"Q1 to Q2",
"Q2 to Q3",
"Q2 to Q3",
"Q3 to Q4",
"Q3 to Q4",
"Q4 to Q5",
"Q4 to Q5",
"Average\nQuarter\nDifference",
"Average\nQuarter\nDifference"),
absence=c(rep(c(TRUE,FALSE),5)),
gpa_difference=c(Q1_to_Q2,
Q2_to_Q3,
Q3_to_Q4,
Q4_to_Q5,
avg_quarter_diff),
stringsAsFactors=TRUE)
# plot difference in data (close up view)
ggplot(GPA_Differences, aes(fill=absence, y=gpa_difference, x=quarter)) +
geom_bar(position="dodge", stat="identity") +
labs(title = "Average Differences in Overall GPA Across Quarters",
subtitle = "(Close-up View)",
x = "Quarter Range",
y = "Change in GPA",
fill = "Took a leave of\nAbsence in\nBetween Quarters?") +
coord_cartesian(ylim = c(-0.5, 0.5)) +
theme(plot.title = element_text(face = "bold", hjust = 0.5),
plot.subtitle = element_text(face = "bold", hjust = 0.5),
panel.grid.major = element_line(linewidth = 0.5, linetype = 'solid',
colour = "black"),
panel.grid.minor.y = element_line(linewidth = 0.25, linetype = 'solid',
colour = "grey"),
panel.background = element_rect(fill = "#F2F2F2", colour = "#FFFFFF",
linewidth = 2, linetype = "solid"),
plot.background = element_rect(color = "black",
linewidth = 1.5))
# plot difference in data (GPA view for bigger picture)
ggplot(GPA_Differences, aes(fill=absence, y=gpa_difference, x=quarter)) +
geom_bar(position="dodge", stat="identity") +
labs(title = "Average Differences in Overall GPA Across Quarters",
subtitle = "(GPA Range View)",
x = "Quarter Range",
y = "Change in GPA",
fill = "Took a leave of\nAbsence in\nBetween Quarters?") +
coord_cartesian(ylim = c(-1, 5)) +
theme(plot.title = element_text(face = "bold", hjust = 0.5),
plot.subtitle = element_text(face = "bold", hjust = 0.5),
panel.grid.major = element_line(linewidth = 0.5, linetype = 'solid',
colour = "black"),
panel.grid.minor.y = element_line(linewidth = 0.25, linetype = 'solid',
colour = "grey"),
panel.background = element_rect(fill = "#F2F2F2", colour = "#FFFFFF",
linewidth = 2, linetype = "solid"),
plot.background = element_rect(color = "black",
linewidth = 1.5)) +
scale_y_continuous(n.breaks = 7)
Taking Leaves of Absence
The blue bars on the
graphs above represent the change in overall GPA when students take
leaves of absence, and we can see that the majority of the change in GPA
is negative, which works to support my hypothesis that the impact of
enrolling in non-consecutive quarters will result in a worsened academic
performance when a break is taken in between quarters.
There is one exception to this, which is the change in overall GPA in between Q3 and Q4, in which students who took a break prior to starting Q4 actually experienced an increased GPA compared to their GPA in Q3. However, when the change in GPA is averaged over all quarters, we still see that students who take leaves of absence experience a decrease in overall GPA that is 7 times greater than the average increase in overall GPA of students who enroll in consecutive quarters.
Staying Enrolled in Consecutive Quarters
The red
bars represent the change in overall GPA when students enroll in
consecutive quarters, and we observe that there is generally a
negligible increase in GPA across quarters. Over the course of Q1 to Q2,
we see a change in GPA that is practically 0, and we see a similar
change in GPA when the change in GPA is averaged from all quarters. From
this, we can conclude that students generally maintain or slightly
increase their GPA when they stay enrolled for consecutive quarters.
These conclusions are easier drawn when looking at the Close-up View graph because the differences in GPA between students who take leaves of absence and students who stay enrolled are larger relative to each other. However, the GPA Range View graph shows the larger perspective and how the changes in GPA will affect GPA when GPA scores can range from 0 to 5. With this view, the change in GPA for consecutive quarter enrollment is negligible and can barely be seen. On the other hand, GPA decreases across quarters due to leaves of absence are more easily visible, with the change from Q1 to Q2 being the most prevalent. The averaged change in GPA is still visually negative for students who took leaves of absence, which suggests that while being continually enrolled in classes may have negligible effects on GPA, taking leaves of absence may cause minor decreases in overall GPA.
Concessions to Conclusions
One thing to keep in
mind is that the sample sizes for students who took leaves in between
quarters are significantly smaller than students who were continually
enrolled in courses. The largest ratio of students who took breaks to
students who stayed enrolled in a single quarter was 7 to 43, and the
smallest ratio was 2 to 48. Because of this disparity and smaller sample
size, the conclusions drawn from this data may be inaccurate (or at the
very least, exaggerated) in comparison to real-world populations. It is
possible for these few students to be affected by unknown external
factors leading to the decreases in their overall GPA over time.
Nonetheless, the trend of worsening GPA over time is still present
within this data set.
Students may use this data and the conclusions drawn from it to
inform their decision whether to stay enrolled in college in consecutive
quarters or to take leaves of absence for whatever reason they may have.