Code
library(tidyr)
library(dplyr)
library(ggplot2)In this project, I will analyze monthly patient visits across 10 community health clinics during 2025.
The original dataset is in wide format, where each clinic has one row and monthly patient visit counts are stored in separate columns. I will use R to transform the dataset into tidy format and then analyze how patient visits vary across clinics and months.
The goal of this project is to practice data tidying and transformation while exploring patterns in patient visits.
Original Dataset: https://brightspace.cuny.edu/d2l/le/1404182/discussions/threads/5822251/View
First, I will import the CSV file into R and examine its structure to understand how the data is organized.
Next, I will use pivot_longer() from the tidyr package to transform the dataset from wide to long format. I will also rename the columns to make them easier to understand.
After tidying the data, I will check for missing values and data consistency. I will also identify the minimum and maximum monthly patient visits for each clinic and calculate summary statistics, including the mean, median, and standard deviation.
Finally, I will calculate total patient visits by clinic and by month. I will use a bar chart to compare clinics and a line chart to examine monthly changes throughout 2025.
One possible challenge is transforming the monthly columns into a single month column while keeping the correct clinic names and patient visit counts.
Another challenge is making sure that the months appear in chronological order rather than alphabetical order, especially in the monthly visualization.
I will use three R packages for this project. The tidyr package will help me transform the dataset from wide to long format. I will use dplyr to clean the data and calculate summary statistics. Finally, I will use ggplot2 to create charts and visualize patterns in monthly patient visits.
library(tidyr)
library(dplyr)
library(ggplot2)I will import the Monthly Patient Visits dataset from my GitHub repository using the read.csv2() function. I will keep the original column names and display the first six rows to examine how the data is organized.
Data Source: https://brightspace.cuny.edu/d2l/le/1404182/discussions/threads/5822251/View
data_url <- "https://raw.githubusercontent.com/OzgeG01/DATA607-Assignment/refs/heads/main/monthly_patient_visits.csv"
patient_raw <- read.csv2(data_url, check.names = FALSE)
knitr::kable(head(patient_raw))| Clinic | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Harbor Community Health Center | 245 | 231 | 260 | 278 | 290 | 301 | 315 | 309 | 287 | 295 | 310 | 325 |
| Riverside Family Health Clinic | 190 | 205 | 198 | 220 | 235 | 241 | 250 | 263 | 255 | 270 | 268 | 280 |
| Central Community Health Center | 310 | 298 | 325 | 340 | 355 | 348 | 370 | 365 | 380 | 392 | 401 | 415 |
| Eastside Family Clinic | 155 | 162 | 170 | 168 | 180 | 195 | 201 | 210 | 205 | 218 | 225 | 230 |
| Westview Community Health Center | 270 | 265 | 280 | 295 | 310 | 320 | 318 | 330 | 342 | 350 | 360 | 375 |
| Northside Health Clinic | 225 | 218 | 240 | 251 | 260 | 272 | 280 | 275 | 290 | 298 | 305 | 315 |
Before tidying the dataset, I will use str() to examine the column names and data types. This will help me understand the structure of the original wide-format dataset.
str(patient_raw)'data.frame': 10 obs. of 13 variables:
$ Clinic: chr "Harbor Community Health Center" "Riverside Family Health Clinic" "Central Community Health Center" "Eastside Family Clinic" ...
$ Jan : int 245 190 310 155 270 225 180 290 205 165
$ Feb : int 231 205 298 162 265 218 175 282 212 170
$ Mar : int 260 198 325 170 280 240 192 300 220 182
$ Apr : int 278 220 340 168 295 251 205 315 230 190
$ May : int 290 235 355 180 310 260 215 325 242 198
$ Jun : int 301 241 348 195 320 272 220 340 250 205
$ Jul : int 315 250 370 201 318 280 230 350 245 215
$ Aug : int 309 263 365 210 330 275 238 345 260 220
$ Sep : int 287 255 380 205 342 290 242 360 268 228
$ Oct : int 295 270 392 218 350 298 250 372 275 235
$ Nov : int 310 268 401 225 360 305 255 380 285 240
$ Dec : int 325 280 415 230 375 315 265 395 292 250
The dataset contains 10 observations and 13 variables. The Clinic column contains clinic names as character values, while the 12 monthly columns (Jan to Dec) contain patient visit counts as integers. Each row represents one clinic. The data is currently in wide format because monthly visits are stored in separate columns.
I will rename the Clinic column to ClinicName to make the variable name more descriptive. I will keep the monthly column names unchanged because they are already clear and easy to understand.
patient_renamed <- patient_raw %>%
rename(
ClinicName = Clinic
)
knitr::kable(head(patient_renamed))| ClinicName | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Harbor Community Health Center | 245 | 231 | 260 | 278 | 290 | 301 | 315 | 309 | 287 | 295 | 310 | 325 |
| Riverside Family Health Clinic | 190 | 205 | 198 | 220 | 235 | 241 | 250 | 263 | 255 | 270 | 268 | 280 |
| Central Community Health Center | 310 | 298 | 325 | 340 | 355 | 348 | 370 | 365 | 380 | 392 | 401 | 415 |
| Eastside Family Clinic | 155 | 162 | 170 | 168 | 180 | 195 | 201 | 210 | 205 | 218 | 225 | 230 |
| Westview Community Health Center | 270 | 265 | 280 | 295 | 310 | 320 | 318 | 330 | 342 | 350 | 360 | 375 |
| Northside Health Clinic | 225 | 218 | 240 | 251 | 260 | 272 | 280 | 275 | 290 | 298 | 305 | 315 |
I will use pivot_longer() from the tidyr package to transform the dataset from wide to long format. The 12 monthly columns will be combined into two columns: Month and PatientVisits. The ClinicName column will remain unchanged. Each row will represent the number of patient visits for one clinic in one month.
patient_long <- patient_renamed %>%
pivot_longer(
cols = Jan:Dec,
names_to = "Month",
values_to = "PatientVisits"
)
head(patient_long)# A tibble: 6 × 3
ClinicName Month PatientVisits
<chr> <chr> <int>
1 Harbor Community Health Center Jan 245
2 Harbor Community Health Center Feb 231
3 Harbor Community Health Center Mar 260
4 Harbor Community Health Center Apr 278
5 Harbor Community Health Center May 290
6 Harbor Community Health Center Jun 301
After transforming the dataset into long format, I will check for missing values in each column. This will help me determine whether any clinic names, months, or patient visit counts are missing before continuing with the analysis.
patient_long %>%
summarise(
ClinicNameMissing = sum(is.na(ClinicName)),
MonthMissing = sum(is.na(Month)),
PatientVisitsMissing = sum(is.na(PatientVisits))
)# A tibble: 1 × 3
ClinicNameMissing MonthMissing PatientVisitsMissing
<int> <int> <int>
1 0 0 0
The missing value check showed that there are no missing values in the ClinicName, Month, or PatientVisits columns. Therefore, no rows need to be removed or modified due to missing data.
I will check the PatientVisits column for unusual values, such as negative numbers or decimal values. Since patient visits represent counts, all values should be non-negative whole numbers. This check will help me identify any potential data inconsistencies before continuing with the analysis.
patient_long %>%
summarise(
NegativeValues = sum(PatientVisits < 0),
NonIntegerValues = sum(PatientVisits %% 1 != 0)
)# A tibble: 1 × 2
NegativeValues NonIntegerValues
<int> <int>
1 0 0
The results show that there are no negative or decimal values in the PatientVisits column. All patient visit counts are non-negative whole numbers. Therefore, no corrections are needed for these values, and the dataset is ready for further analysis.
After checking the data for missing and unusual values, I will calculate summary statistics for monthly patient visits. I will calculate the number of observations, mean, median, minimum, maximum, and standard deviation for each clinic. These statistics will help me compare patient visit counts across clinics and identify differences in their monthly activity.
patient_summary <- patient_long %>%
group_by(ClinicName) %>%
summarise(
Count = n(),
Mean = round(mean(PatientVisits), 2),
Median = median(PatientVisits),
Min = min(PatientVisits),
Max = max(PatientVisits),
SD = round(sd(PatientVisits), 2),
.groups = "drop"
)
knitr::kable(patient_summary)| ClinicName | Count | Mean | Median | Min | Max | SD |
|---|---|---|---|---|---|---|
| Central Community Health Center | 12 | 358.25 | 360.0 | 298 | 415 | 36.13 |
| Eastside Family Clinic | 12 | 193.25 | 198.0 | 155 | 230 | 25.67 |
| Greenwood Family Health Center | 12 | 222.25 | 225.0 | 175 | 265 | 29.63 |
| Harbor Community Health Center | 12 | 287.17 | 292.5 | 231 | 325 | 28.95 |
| Hillcrest Community Clinic | 12 | 208.17 | 210.0 | 165 | 250 | 27.82 |
| Lakeside Community Clinic | 12 | 337.83 | 342.5 | 282 | 395 | 36.22 |
| Northside Health Clinic | 12 | 269.08 | 273.5 | 218 | 315 | 31.11 |
| Parkview Health Center | 12 | 248.67 | 247.5 | 205 | 292 | 28.40 |
| Riverside Family Health Clinic | 12 | 239.58 | 245.5 | 190 | 280 | 30.23 |
| Westview Community Health Center | 12 | 317.92 | 319.0 | 265 | 375 | 35.56 |
The summary statistics show that Central Community Health Center had the highest average monthly patient visits (358.25), followed by Lakeside Community Clinic (337.83) and Westview Community Health Center (317.92). Eastside Family Clinic had the lowest monthly average (193.25). Each clinic had 12 monthly observations. The standard deviations ranged from 25.67 at Eastside Family Clinic to 36.22 at Lakeside Community Clinic, showing that monthly patient visits varied across clinics.
I will calculate the total number of patient visits for each clinic during 2025. I will group the data by clinic and sum the monthly patient visits. This will help me compare the overall patient volume across the 10 clinics and identify which clinics had the highest and lowest total visits.
patient_clinic_totals <- patient_long %>%
group_by(ClinicName) %>%
summarise(
TotalVisits = sum(PatientVisits),
.groups = "drop"
) %>%
arrange(desc(TotalVisits))
patient_clinic_totals# A tibble: 10 × 2
ClinicName TotalVisits
<chr> <int>
1 Central Community Health Center 4299
2 Lakeside Community Clinic 4054
3 Westview Community Health Center 3815
4 Harbor Community Health Center 3446
5 Northside Health Clinic 3229
6 Parkview Health Center 2984
7 Riverside Family Health Clinic 2875
8 Greenwood Family Health Center 2667
9 Hillcrest Community Clinic 2498
10 Eastside Family Clinic 2319
The results show that Central Community Health Center had the highest total number of patient visits in 2025, with 4,299 visits. Lakeside Community Clinic ranked second with 4,054 visits, followed by Westview Community Health Center with 3,815 visits. Eastside Family Clinic had the lowest total, with 2,319 visits. These results show differences in patient volume across the 10 clinics.
I will create a bar chart to compare the total number of patient visits across the 10 clinics in 2025. I will arrange the clinics from the highest to the lowest number of visits to make the differences easier to see.
ggplot(patient_clinic_totals,
aes(x = reorder(ClinicName, TotalVisits),
y = TotalVisits)) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(
title = "Total Patient Visits by Clinic in 2025",
x = "Clinic",
y = "Total Patient Visits"
) +
theme_minimal()The bar chart shows that Central Community Health Center had the highest total number of patient visits in 2025, with 4,299 visits. Lakeside Community Clinic followed with 4,054 visits. Eastside Family Clinic had the lowest total, with 2,319 visits. The chart makes it easier to compare patient volumes across the 10 clinics and shows that some clinics served considerably more patients than others.
I will calculate the total number of patient visits for each month in 2025 across all 10 clinics. I will group the data by month and sum the patient visits. I will also arrange the months in chronological order from January to December. This will help me identify which months had the highest and lowest patient visits.
patient_monthly_totals <- patient_long %>%
mutate(
Month = factor(Month, levels = month.abb)
) %>%
group_by(Month) %>%
summarise(
TotalVisits = sum(PatientVisits),
.groups = "drop"
)
patient_monthly_totals# A tibble: 12 × 2
Month TotalVisits
<fct> <int>
1 Jan 2235
2 Feb 2218
3 Mar 2367
4 Apr 2492
5 May 2610
6 Jun 2692
7 Jul 2774
8 Aug 2815
9 Sep 2857
10 Oct 2955
11 Nov 3029
12 Dec 3142
The monthly totals show that patient visits generally increased throughout 2025. February had the lowest total with 2,218 visits, while December had the highest total with 3,142 visits. Patient visits increased from 2,235 in January to 3,142 in December. Although there was a small decrease in February, the overall trend shows increasing patient visits across the 10 clinics during the year.
I will create a line chart to visualize the total number of patient visits across all 10 clinics for each month in 2025. This chart will help me identify monthly trends and changes in patient volume.
ggplot(patient_monthly_totals,
aes(x = Month, y = TotalVisits, group = 1)) +
geom_line(color = "steelblue", linewidth = 1) +
geom_point(color = "steelblue", size = 2) +
labs(
title = "Monthly Patient Visits in 2025",
x = "Month",
y = "Total Patient Visits"
) +
theme_minimal()The line chart shows an overall upward trend in patient visits throughout 2025. Total visits decreased slightly from 2,235 in January to 2,218 in February, but increased steadily from March through December. December had the highest number of visits (3,142), while February had the lowest (2,218). This pattern shows that patient visits increased across the 10 clinics during the year.
In this project, I analyzed monthly patient visits across 10 community health clinics during 2025. I transformed the original dataset from wide to long format using pivot_longer() and checked for missing and unusual values. The dataset contained no missing values, negative counts, or decimal values, so no additional cleaning was needed.
The summary statistics showed differences in patient visits across clinics. Central Community Health Center had the highest total number of visits (4,299), while Eastside Family Clinic had the lowest (2,319).
The monthly analysis showed that patient visits generally increased throughout 2025. February had the lowest total with 2,218 visits, while December had the highest with 3,142 visits. The line chart showed a steady increase in visits from March through December.
Overall, this project helped me practice transforming wide data into tidy format and using summary statistics and visualizations to identify patterns. The results showed differences in patient volume across clinics and an overall increase in monthly visits during 2025.
I used ChatGPT (GPT-5.6 Luna), developed by OpenAI, to help me understand some of the functions I used in this assignment and to check my work.
OpenAI. (2026). ChatGPT (GPT-5.6 Luna) [Large language model]. [https://chatgpt.com/ Accessed October 9, 2026].
Link: