Start date: 1 April 2025

This notebook is located in Y:/IEShare/Reporting/Student Achievement Data/2024-2025.

Student Achievement Data

1. Fall Enrollment

Fall enrollment is commonly used to measure the size of the institution as well as the growth/decline of the college’s student population over time. In CCTC’s 2020-2025 Strategic Plan, college leadership has set a fall enrollment goal of 4,200 students. CCTC has not yet met the ±10% threshold for the fall enrollment goal.

create_year = function(file) {
  str_extract(basename(file), "\\d{4}")
}

VER001_path = "data"

VER001_pattern = "\\d{4} - EDSS_ST_VER001_cers_headcount_by_current_and_previous_year.csv"

VER001_files = list.files(VER001_path, full.names = TRUE)

VER001_matching_files = VER001_files[grepl(VER001_pattern, VER001_files)]

#remove hashtag on data$YEAR once there's data
VER001_data_list = lapply(VER001_matching_files, function(file) {
  data= read.csv(file,colClasses = 'character')
  data$YEAR= create_year(file)
  data
})

VER001_DF= bind_rows(VER001_data_list) %>% 
  data.frame()
#using EDSS-ST-VER001

VER001_CCTC =VER001_DF %>% 
  filter(str_detect(College_name,regex("Central Carolina",ignore_case = T))) %>% 
  mutate(P_HeadCount = str_replace_all(Previous_HeadCount, "[^0-9.-]", ""),
         C_HeadCount = str_replace_all(Current_HeadCount, "[^0-9.-]", ""),
         P_HeadCount = as.numeric(P_HeadCount),
         C_HeadCount = as.numeric(C_HeadCount),
         Per_Change = (C_HeadCount - P_HeadCount) / C_HeadCount,
         Percent_Change = paste0(round(Per_Change * 100, 1), "%")) %>%  
  select(YEAR,Previous_HeadCount,Current_HeadCount,Percent_Change,everything())
VER001_CCTC %>% 
  group_by(YEAR,Previous_HeadCount,Current_HeadCount,Percent_Change) %>% 
  count() %>% 
  select(-n) %>% 
  datatable(rownames = F, caption = 'EDSS Report',
  options = list(
    initComplete = JS(
      "function(settings, json) {",
      "$(this.api().table().header()).css({'background-color': '#0d223f', 'color': '#a7a8aa'});",
      "$(this.api().table().body()).css({'color': '#a7a8aa'});",
      "$('tbody tr').css({'background-color': 'white'});",
      "}"
    )
  ),
  class = 'cell-border stripe'
)
# #0d223f - dark blue; #ffb548 - gold; #a7a8aa - gray
VER001_CCTC %>% 
  filter(!is.na(C_HeadCount)) %>% 
  ggplot(aes(y=C_HeadCount,x=YEAR)) +
  geom_col(fill='#a7a8aa')+
  theme_bw()+
  geom_text(aes(label = paste0(C_HeadCount)), 
          color = "#0d223f", 
          position = position_stack(vjust = 0.5)) +
geom_text(aes(label = paste0(" (", Percent_Change, ")")), 
          color = "#0d223f", 
          position = position_stack(vjust = 0.55))+
  guides(fill = "none")+
  labs(title='Fall to Fall Enrollment',x=' ',y='Headcount')+
  theme(plot.title = element_text(hjust = .5))

2. Graduate Placement Rates

Graduate placement rates reflect the success of graduates with respect to employment or continued education. Graduates who are deceased, disabled, and not actively seeking employment (e.g., active military) are exclude from the placement rate. The Performance Funding Indicator defined by the South Carolina Technical College System (SCTCS) sets a target goal of 80% overall graduate placement. CCTC has consistently met or exceeded the established threshold of ±5% for the graduate placement rate.

PLACEMENT = read.xlsx("Y:/Reporting/Student Achievement Data/2024-2025/data/SCTCS Performance Indicator Data 2025 final.xlsx",sheet = 'Placement')

#names(PLACEMENT) = make.names(colnames(PLACEMENT))
#PLACEMENT1[] = lapply(PLACEMENT1, as.character)

# Remove the first row as in your original code
PLACEMENT1= PLACEMENT[-1,]

# Find the row index where "COLLEGE" appears
header_row_index= which(str_detect(PLACEMENT1[[1]], "COLLEGE"))

# Assign column names dynamically
colnames(PLACEMENT1) = as.character(PLACEMENT1[header_row_index, ])

colnames(PLACEMENT1) = make.names(colnames(PLACEMENT1), unique = TRUE)

#checks colnames for errors
#which(is.na(colnames(PLACEMENT1)) | colnames(PLACEMENT1) == "")


colnames(PLACEMENT1) = str_remove(colnames(PLACEMENT1), "^X")       # Remove leading "X"
colnames(PLACEMENT1) = str_replace_all(colnames(PLACEMENT1), "\\.", "-")  # Replace "." with "-"

PLACEMENT2 = PLACEMENT1 %>%
  filter(str_detect(`COLLEGE-NAME` ,"^Central")) %>% 
  pivot_longer(cols = everything())

colnames(PLACEMENT2) =PLACEMENT2[1,]

PLACEMENT3 = PLACEMENT2 %>% 
  rename(Year= `COLLEGE-NAME`,Percentage = `Central Carolina`) %>% 
  filter(str_detect(Year,regex("-2")))
PLACEMENT4 = PLACEMENT3 %>% 
  group_by(Year) %>% 
  mutate(Percentage = percent(as.numeric(Percentage))) %>% 
  tail(n=5)

PLACEMENT4

3. Graduate Production Rates

The graduate production rate is a measure that reflects the college’s fulfillment of its workforce development mission. This rate includes all awards for degrees, diplomas, and certificates and removed time-bound and demographic restrictions. This graduate production rate is based on an unduplicated graduate headcount relative to the fall term full-time-equivalent (FTE). CCTC has consistently met or exceeded the South Carolina Technical College System (SCTCS) Performance Funding benchmark of 20% graduate production given a ±5% threshold action level.

GRAD_PRODUCTION = read.xlsx("Y:/Reporting/Student Achievement Data/2024-2025/data/SCTCS Performance Indicator Data 2024 draft for IE review 5-7-2024.xlsx",sheet = 'Graduate Production')

names(GRAD_PRODUCTION) = make.names(colnames(GRAD_PRODUCTION))
# Remove the first row as in your original code
GRAD_PRODUCTION1= GRAD_PRODUCTION[-1,]

# Find the row index where "COLLEGE" appears
header_row_index= which(str_detect(GRAD_PRODUCTION1[[1]], "^COLLEGE"))[1]

# Move the detected header row to the top
GRAD_PRODUCTION1 =rbind(GRAD_PRODUCTION1[header_row_index, ], GRAD_PRODUCTION1[-header_row_index, ])

# Assign column names dynamically
colnames(GRAD_PRODUCTION1) =GRAD_PRODUCTION1[1,]

# Remove the first row since it is now the column headers
#GRAD_PRODUCTION1=GRAD_PRODUCTION1[-1,]
GRAD_PRODUCTION1 = GRAD_PRODUCTION1 %>% 
  slice(-1:-3) %>% 
  filter(str_detect(`COLLEGE NAME`,"^Central"))

GRAD_PRODUCTION2 = GRAD_PRODUCTION1 %>% 
  pivot_longer(cols = everything())

colnames(GRAD_PRODUCTION2) =GRAD_PRODUCTION2[1,]

GRAD_PRODUCTION3 = GRAD_PRODUCTION2 %>% 
  rename(Year = `COLLEGE NAME`,Percentage = `Central Carolina`) %>% 
  filter(str_detect(Year,regex("-2")))
GRAD_PRODUCTION4= GRAD_PRODUCTION3 %>% 
  group_by(Year) %>% 
  mutate(Percentage = percent(as.numeric(Percentage))) %>% 
  tail(n=5)

GRAD_PRODUCTION4

4. Graduation Rates

CCTC has consistently met or exceeded this goal over the past five years. The IPEDS graduation rate cohort includes all full-time, first-time degree/certificate-seeking undergraduate students. The 150% graduate rate is the percentage of full-time, first-time students who graduate within 150% of normal program completion. CCTC has set a goal of a 15% graduation rate with a ±3% action level.

GRAD_RATES = read.xlsx("Y:/Reporting/Student Achievement Data/2024-2025/data/Graduation_Rates.xlsx")
GRAD_RATES %>% 
  group_by(Year) %>% 
  mutate(Percentage = percent(as.numeric(Percentage))) %>% 
  tail(n=5)

5. Licensure Exam Pass Rates [need to update to the most recent rates]

Annually, the results of professional licensure exams are collected and reported to the Commission on Higher Education (CHE). The South Carolina Technical College System (SCTCS) Chief Academic Officers (CAO) Peer Group has reviewed and recommended licensure exams that should be reported for the 16 technical/community colleges. The licensure exam pass rates CCTC reports to CHE appear in bold on the table below. Licensure/certification exam pass rates for additional CCTC programs are included in the table. CCTC has set a goal of having an overall pass rate for first-time examinees on reported exams to be 80% with a ±5% threshold action level. This is to align with the SCTCS Performance Funding Indicator benchmark.

LICENSURE = read.xlsx('Y:/Reporting/Student Achievement Data/2024-2025/data/Licensure and Certification Results.xlsx')

LICENSURE %>% 
  mutate(across(where(is.numeric), percent)) %>% 
  datatable()

6. Fall-to-Spring Persistence Rates

Persistence rates (also called “retention rates”) are a commonly used student progress measure for both two-year and four-year institutions. The Performance Funding Indicator defined by the South Carolina Technical College System (SCTCS) defines fall-to-spring persistence as the proportion of students enrolled in a fall semester who returned the following spring semester (excluding those who graduated between these semesters). CCTC has consistently met or exceeded the SCTCS target fall-to-spring persistence goal of 71% given a ±5% threshold action level.

PERSISTENCE = read.xlsx("Y:/Reporting/Student Achievement Data/2024-2025/data/SCTCS Performance Indicator Data 2025 final.xlsx",sheet = 'Persistence')
# Remove the first row as in your original code
PERSISTENCE1= PERSISTENCE[-1,]

# Find the row index where "COLLEGE" appears
header_row_index= which(str_detect(PERSISTENCE1[[1]], "COLLEGE"))

# Assign column names dynamically
colnames(PERSISTENCE1) = as.character(PERSISTENCE1[header_row_index, ])

colnames(PERSISTENCE1) = make.names(colnames(PERSISTENCE1), unique = TRUE)

#checks colnames for errors
#which(is.na(colnames(PERSISTENCE1)) | colnames(PERSISTENCE1) == "")


colnames(PERSISTENCE1) = str_remove(colnames(PERSISTENCE1), "^X")       # Remove leading "X"
colnames(PERSISTENCE1) = str_replace_all(colnames(PERSISTENCE1), "\\.", "-")  # Replace "." with "-"

PERSISTENCE2 = PERSISTENCE1 %>%
  filter(str_detect(`COLLEGE-NAME` ,"^Central")) %>% 
  pivot_longer(cols = everything())

colnames(PERSISTENCE2) =PERSISTENCE2[1,]

PERSISTENCE3 = PERSISTENCE2 %>% 
  rename(Year= `COLLEGE-NAME`,Percentage = `Central Carolina`) %>% 
  filter(str_detect(Year,regex("-2")))
PERSISTENCE4 = PERSISTENCE3 %>% 
  group_by(Year) %>% 
  mutate(Percentage = percent(as.numeric(Percentage))) %>% 
  tail(n=5)

PERSISTENCE4

7. Fall-to-Fall Retention Rates

As a two-year institution, CCTC measures its students’ progress towards an associate’s degree by tracking the percent of first-time students enrolled a fall semester who are still enrolled during the fall semester of the next year. In the 2020-2025 Strategic Plan, college leadership set a goal to achieve 65% fall-to-fall retention for first-time, full-time freshmen, and to achieve 40% fall-to-fall retention for first-time, part-time freshman. CCTC is very close to meeting the ±5% threshold for each of these benchmarks.

[Can also use Retention Dashboard]


SELECT STVTERM_DESC,SFRSTCR_TERM_CODE,SFRSTCR_PIDM,SGBSTDN_STYP_CODE,STVSTYP_DESC, SFRSTCR_CREDIT_HR

FROM SFRSTCR

LEFT JOIN STVTERM
ON SFRSTCR_TERM_CODE = STVTERM_CODE

LEFT JOIN SGBSTDN
ON SFRSTCR_PIDM = SGBSTDN_PIDM

LEFT JOIN STVSTYP
ON SGBSTDN_STYP_CODE = STVSTYP_CODE

WHERE SGBSTDN_TERM_CODE_EFF = (SELECT MAX(A.SGBSTDN_TERM_CODE_EFF)
                                FROM SGBSTDN A
                                WHERE A.SGBSTDN_PIDM = SFRSTCR_PIDM
                                  AND A.SGBSTDN_TERM_CODE_EFF <= SFRSTCR_TERM_CODE)
                                  
AND SFRSTCR_RSTS_CODE IN ('RE','RW','AU','AW','WS','WM')

--change the SFRSTCR_TERM_CODE to match the desired semesters!
AND SFRSTCR_TERM_CODE >= 201810
AND SFRSTCR_TERM_CODE <= 202310
SQL_retention %>% 
  distinct(SFRSTCR_TERM_CODE,SFRSTCR_PIDM,.keep_all = T) %>% 
  group_by(STVTERM_DESC) %>% 
  count()
#order STVTERM with SFRSTCR
SQL_retention = SQL_retention %>% 
  mutate(STVTERM_DESC = factor(STVTERM_DESC,levels=STVTERM_DESC[order(SFRSTCR_TERM_CODE)] %>%
  unique()))

RETENTION = SQL_retention %>% 
  group_by(STVTERM_DESC,SFRSTCR_TERM_CODE,SFRSTCR_PIDM,STVSTYP_DESC) %>% 
  summarise(total_cred_hours = sum(SFRSTCR_CREDIT_HR,na.rm = T)) %>% 
  mutate(enrollment_status = case_when(total_cred_hours >= 12 ~ "FULL",
                                       TRUE ~ 'PART'))%>% 
  arrange(SFRSTCR_PIDM, SFRSTCR_TERM_CODE) %>%
  mutate(current_year = as.numeric(substr(SFRSTCR_TERM_CODE, 1, 4)),
    term_suffix = substr(SFRSTCR_TERM_CODE, 5, 6),target_return_term = paste0(current_year + 1, term_suffix)) %>%
  group_by(SFRSTCR_PIDM) %>%
  mutate(returned_in_target_term = case_when(target_return_term %in% SFRSTCR_TERM_CODE ~ "RETAINED",
         TRUE ~ "NOT_RETAINED"))
#don't include this snippet; checking to see numbers
see=RETENTION %>% 
  filter(str_detect(STVTERM_DESC,regex('fall',ignore_case = T))) %>% 
  distinct(STVTERM_DESC,SFRSTCR_PIDM,STVSTYP_DESC,.keep_all = T)

see1 = see %>% 
  group_by(STVTERM_DESC,returned_in_target_term) %>% 
  count() %>% 
  pivot_wider(names_from = returned_in_target_term,values_from = n) %>% 
  arrange(STVTERM_DESC) %>% 
  sum_cols() %>% 
  sum_rows()

see %>% 
  group_by(STVTERM_DESC,returned_in_target_term) %>% 
  count() %>% 
  pivot_wider(names_from = returned_in_target_term,values_from = n)
#match with Argos DASH 007 Retention Dashboard; filter for First Time Freshman and Fall terms
RET_ENROLLMENT_STATUS = RETENTION %>%
  filter(str_detect(STVSTYP_DESC,regex('first time',ignore_case = T)),
         str_detect(STVTERM_DESC,regex('fall',ignore_case = T))) %>% 
  distinct(STVTERM_DESC,SFRSTCR_PIDM,.keep_all = T) %>% 
  group_by(STVTERM_DESC,enrollment_status) %>% 
  count() %>% 
  pivot_wider(names_from = enrollment_status,values_from = n) %>% 
  arrange(STVTERM_DESC) %>% 
  ungroup()
RET_RETAINED = RETENTION %>%
  filter(str_detect(STVSTYP_DESC,regex('first time',ignore_case = T)),
         str_detect(STVTERM_DESC,regex('fall',ignore_case = T))) %>% 
  filter(returned_in_target_term=='RETAINED') %>% 
  group_by(STVTERM_DESC,enrollment_status,returned_in_target_term) %>% 
  count() %>% 
  pivot_wider(names_from = returned_in_target_term,values_from = n) %>% 
  pivot_wider(names_from = enrollment_status,values_from = 3)
#join the two DFs by TERM to create retention rate table
RET_JOIN = RET_ENROLLMENT_STATUS %>% 
  left_join(RET_RETAINED,by=join_by(STVTERM_DESC==STVTERM_DESC)) %>% 
  rename(Enrolled_FT=FULL.x,Enrolled_PT = PART.x,
         Retained_FT = FULL.y,Retained_PT = PART.y) %>% 
  filter(!is.na(Retained_FT))

RET_JOIN = RET_JOIN%>% 
  mutate(Retention_Rate_FT = percent(Retained_FT/Enrolled_FT,1),
         Retention_Rate_PT = percent(Retained_PT/Enrolled_PT,1))
RET_JOIN %>% 
  select(STVTERM_DESC,Retention_Rate_FT,Retention_Rate_PT)

8. Student Success Rates

The student success rate is a cohort-based measure of graduation, transfer to another postsecondary institution in South Carolina, or continuing enrollment after three years of first-time enrollment. The cohort includes all first-time freshman enrolling in degree, diploma, or certificate programs in a given fall semester. The Performance Funding Indicator defined by the South Carolina Technical College System (SCTCS) sets a target goal of 49% student success. Over the past five years, CCTC has shown continuous improvement, and the college met the ±5% threshold for this benchmark with the most recent student cohort.

#ignore relacing Excel with SCTCS Performance Indicator Data 2025 final.xlsx
SUCCESS_RATE = read.xlsx("Y:/Reporting/Student Achievement Data/2024-2025/data/SCTCS Performance Indicator Data 2024 draft for IE review 5-7-2024.xlsx",sheet = 'Success Rate')
SUCCESS_RATE1= SUCCESS_RATE[-1,]

# Find the row index where "COLLEGE" appears
header_row_index= which(str_detect(SUCCESS_RATE1[[1]], "^COLLEGE"))

# Assign column names dynamically
colnames(SUCCESS_RATE1) = as.character(SUCCESS_RATE1[header_row_index, ])

colnames(SUCCESS_RATE1) = make.names(colnames(SUCCESS_RATE1), unique = TRUE)

#checks colnames for errors
#which(is.na(colnames(SUCCESS_RATE1)) | colnames(SUCCESS_RATE1) == "")


colnames(SUCCESS_RATE1) = str_remove(colnames(SUCCESS_RATE1), "^X")       # Remove leading "X"

colnames(SUCCESS_RATE1) = str_replace_all(colnames(SUCCESS_RATE1), "\\.", "-")  # Replace "." with "-"

colnames(SUCCESS_RATE1) = sapply(colnames(SUCCESS_RATE1), function(name) {
  if (grepl("-Cohort$", name)) {
    year = as.numeric(sub("-Cohort$", "", name))
    if (!is.na(year)) {
      return(paste0(year, "-", year + 3))
    }
  }
  return(name)
})

SUCCESS_RATE2 = SUCCESS_RATE1 %>%
  filter(str_detect(`COLLEGE-NAME` ,"^Central")) %>% 
  pivot_longer(cols = everything())

colnames(SUCCESS_RATE2) =SUCCESS_RATE2[1,]

SUCCESS_RATE3 = SUCCESS_RATE2 %>% 
  rename(Year= `COLLEGE-NAME`,Percentage = `Central Carolina`) %>% 
  filter(str_detect(Year,regex("-2")))
SUCCESS_RATE4 = SUCCESS_RATE3 %>% 
  group_by(Year) %>% 
  mutate(Percentage = percent(as.numeric(Percentage))) %>% 
  tail(n=5)

SUCCESS_RATE4