library(tidyverse)
library(pheatmap)
library(viridis)
enrollment <- readr::read_csv("Montgomery_College_Enrollment_Data_20261008.csv")
#loading the dataset and libraryProject1: Who Attends Montgomery College? Fall 2015 Enrollment
The Dataset:
The data was taken from data.montgomerycountymd.govand is about Montgomery College Student Enrollment. It contains 25k rows and 18 variables which describes students features, where and when they are attending and information about high schools origins.
The variables I use are:
City in MD: City High School was located in MD. Categorical.
Age Group: Age Range of Enrollee. Categorical.
HS Category: Description of High School attended. Categorical.
MCPS High School: Montgomery County Public School attended. Categorical, transformed in numeric by grouping students by school.
Student Status: Part or Full time enrollment. Categorical.
Attend Day or Evening: Time of Day primarily attended. Categorical, transformed in percentage.
Gender: Student Gender. Categorical, transformed in percentage.
Student Type: Status of student enrolled. Categorical, transformed in percentage.
For this project, I focused on differences between groups. First, how students from five cities that send the most students to the college were distributed across age. Second, profiles of the MCPS high schools that send the most students to college were compared using “Full-time students”, “evening students”, “female students”, and “continuing students”.
glimpse (enrollment) Rows: 25,320
Columns: 18
$ `Fall Term` <dbl> 2015, 2015, 2015, 2015, 2015, 2015, 2015, 2…
$ `Student Type` <chr> "Continuing", "Continuing", "Continuing", "…
$ `Student Status` <chr> "Full-Time", "Part-Time", "Part-Time", "Ful…
$ Gender <chr> "Female", "Male", "Male", "Male", "Female",…
$ Ethnicity <chr> "Not Hispanic", "Not Hispanic", "Not Hispan…
$ Race <chr> "White", "White", "Black", "Asian", "White"…
$ `Attending Germantown` <chr> "Yes", "No", "No", "No", "No", "Yes", "Yes"…
$ `Attending Rockville` <chr> "Yes", "Yes", "Yes", "Yes", "Yes", "No", "N…
$ `Attending Takoma Park/SS` <chr> "No", "No", "No", "No", "No", "No", "No", "…
$ `Attend Day or Evening` <chr> "Day Only", "Evening Only", "Day & Evening"…
$ `MC Program Description` <chr> "Health Sciences (Pre-Clinical Studies)", "…
$ `Age Group` <chr> "25 - 29", "21 - 24", "20 or Younger", "20 …
$ `HS Category` <chr> "Foreign Country", "MCPS", "MCPS", "MCPS", …
$ `MCPS High School` <chr> NA, "Sherwood High School", "Quince Orchard…
$ `City in MD` <chr> "Bethesda", "Olney", "Gaithersburg", "North…
$ State <chr> "MD", "MD", "MD", "MD", "MD", "MD", "MD", "…
$ ZIP <dbl> 20816, 20832, 20877, 20878, 20906, 20876, 2…
$ `County in MD` <chr> "Montgomery", "Montgomery", "Montgomery", "…
#visualizing all the variables and what type are theyInspecting and cleaning the data
colSums(is.na(enrollment)) Fall Term Student Type Student Status
0 0 0
Gender Ethnicity Race
0 0 0
Attending Germantown Attending Rockville Attending Takoma Park/SS
0 0 0
Attend Day or Evening MC Program Description Age Group
0 0 0
HS Category MCPS High School City in MD
0 11762 97
State ZIP County in MD
8 99 0
#checking if there is any missing valueenrollment |>
count(`Fall Term`)# A tibble: 1 × 2
`Fall Term` n
<dbl> <int>
1 2015 25320
#Each students were tagged as 2015 in this dataset, I use count to see how many students were in the datasetenrollment |>
count(`HS Category`, is.na(`MCPS High School`))# A tibble: 7 × 3
`HS Category` `is.na(\`MCPS High School\`)` n
<chr> <lgl> <int>
1 Foreign Country TRUE 4910
2 GED TRUE 516
3 Home-Schooled TRUE 229
4 MCPS FALSE 13558
5 Mont.County Other TRUE 710
6 Other Maryland TRUE 1614
7 Other State TRUE 3783
#counting and visualizing the students according to HS categoryenrollment1 <- enrollment |>
mutate(`MCPS High School` = replace_na(`MCPS High School`, "Not MCPS"), #replacing NA for Students that are not from MCPS
ZIP = as.character(ZIP)) #mutate zip to categorical
#I only cleaned MCPS High School; City in MD will be filtered in graphs and Gender/Age Group have few values that will not affect our data exploration.colSums(is.na(enrollment1)) Fall Term Student Type Student Status
0 0 0
Gender Ethnicity Race
0 0 0
Attending Germantown Attending Rockville Attending Takoma Park/SS
0 0 0
Attend Day or Evening MC Program Description Age Group
0 0 0
HS Category MCPS High School City in MD
0 0 97
State ZIP County in MD
8 99 0
#verifying if the NA were correctly replacedData Visualization
top_cities <- enrollment1 |>
filter(!is.na(`City in MD`)) |>
count(`City in MD`) |>
slice_max(n, n = 5)
top_cities# A tibble: 5 × 2
`City in MD` n
<chr> <int>
1 Silver Spring 7464
2 Gaithersburg 3220
3 Rockville 2925
4 Germantown 2675
5 Montgomery Village 901
#filtering by cities that sent more students to MC.enrollment_top <- enrollment1 |>
filter(`City in MD` %in% top_cities$`City in MD`)
#filter top city within MDggplot(enrollment_top, aes(x = `Age Group`, fill = `City in MD`)) +
geom_bar() +
scale_fill_viridis_d() +
theme_bw() +
labs(title = "Students from the Top 5 Cities by Age Group",
x = "Age group",
y = "Number of students",
fill = "City",
caption = "Source: Montgomery County, MD Open Data Portal (dataMontgomery)")#Bar chart shows top cities by age grouphs_summary <- enrollment |>
filter(`HS Category` == "MCPS") |>
group_by(`MCPS High School`) |>
summarise(n_students = n(),
'Full-Time (%)' = mean(`Student Status` == "Full-Time") * 100,
'Evening Only (%)' = mean(`Attend Day or Evening` == "Evening Only") * 100,
'Female (%)' = mean(Gender == "Female") * 100,
'Continuing (%)' = mean(`Student Type` == "Continuing") * 100,
.groups = "drop")
head(hs_summary)# A tibble: 6 × 6
`MCPS High School` n_students `Full-Time (%)` `Evening Only (%)` `Female (%)`
<chr> <int> <dbl> <dbl> <dbl>
1 Albert Einstein HS… 655 34.7 7.33 54.0
2 Bethesda Chevy Cha… 357 38.4 10.1 45.9
3 Clarksburg High Sc… 576 47.2 5.90 50.2
4 Colonel Zadok Magr… 688 38.1 10.5 49.6
5 Damascus High Scho… 391 40.4 8.70 47.3
6 Gaithersburg High … 842 33.8 9.26 54.9
# ℹ 1 more variable: `Continuing (%)` <dbl>
#group all MCPS, count number of students and calculate the mean for Full-Time, Evening Only, Female and Continuingtop_hs <- hs_summary |>
slice_max(n_students, n = 5)
top_matrix <- data.matrix(top_hs[, -c(1,2)])
row.names(top_matrix) <- top_hs$`MCPS High School`
class(top_matrix)[1] "matrix" "array"
#Turn it into a matrix with HS as row namespheatmap(top_matrix,
cluster_rows = FALSE,
cluster_cols = FALSE,
scale = "column",
display_numbers = round(top_matrix, 1),
number_color = "white",
color = viridis(25),
legend = TRUE,
legend_breaks = c(-1.5, 0, 1.5),
legend_labels = c("Lower than\nother schools", "Average", "Higher than\nother schools"),
angle_col = 45,
main = "Students of MC per school MCPS\nSource: MD Open Data Portal")#Heat Map showing the percent of each class by MCPS
#When Legend = True, legend_breaks and legend_labels were used to replace the numbers (-1.5 to 1.5) with labels that explain the colorsFindings and explanation
The first step of this project consisted in specting, understanding and cleaning the data; Three variables had NA: “MCPS High School” (11,762), “City in MD” (97), and “ZIP” (99). After analysis, the NA in “MCPS High School” were not considered errors, because they belong to students who did not attend an MCPS high school (for example students from a foreign country), they were replaced them with “Not MCPS”. Additionally, converted `ZIP` from an integer to a character variable, since a ZIP code is an identifier. The 97 students without a city were removed with ‘is.na’ when I selected the five cities that send the most students.
The bar chart shows the age group distribution of students from the five cities that send the most students to Montgomery College. Silver Spring sends more than twice as many students as any other city (7,464). The 20 or younger group is the tallest bar in every city, and 25 to 29 is the shortest.
The heat map compares the five MCPS high schools that send the most students. The schools are quite similar: full-time students range from 34.7% to 39.2%, evening only range from 7.3% to 10.5% and continuing students from 68.2% to 77.9%. The clearest differences are in gender, where Gaithersburg (54.9%) has the highest share of female students and Northwest (46.4%) the lowest; Almost 10% if compared.
The `pheatmap` function does not have a caption, so I added the data source to the title. I also wanted to show the age groups as percentages within each city, which would make the small cities easier to compare with Silver Spring.