My data set is about the 2023 marathon in boston this dataset includes 2 catergorical varibales age and gender and one qantative varible which is finsih net times so in my project i will be showing Which runner, the top male or top female, was more remarkable in comparison to their respective fields?The dataset contain information about participants in the 2023 Boston Marathon. This includes details such as age, gender, nationality, race times, and potentially additional demographic or performance-related variables. The data was sourced from the SCORE Network, a platform dedicated to sports data and analytics. thie source of this dataset is from https://data.scorenetwork.org/running/boston_marathon_2023.html.
library(readr)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
boston_marathon_2023 <- read_csv("https://data.scorenetwork.org/data/boston_marathon_2023.csv")
## Rows: 26598 Columns: 15
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (8): age_group, name, team, bib_number, half_time, finish_net, finish_gu...
## dbl (7): place_overall, place_gender, place_division, half_time_sec, finish_...
##
## ℹ 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.
str(boston_marathon_2023)
## spc_tbl_ [26,598 × 15] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ age_group : chr [1:26598] "18-39" "18-39" "18-39" "18-39" ...
## $ place_overall : num [1:26598] 1 2 3 4 5 6 7 8 9 10 ...
## $ place_gender : num [1:26598] 1 2 3 4 5 6 7 8 9 10 ...
## $ place_division : num [1:26598] 1 2 3 4 5 6 7 8 9 10 ...
## $ name : chr [1:26598] "Chebet, Evans" "Geay, Gabriel" "Kipruto, Benson" "Korir, Albert" ...
## $ team : chr [1:26598] "Team–" "Team–" "Team–" "Team–" ...
## $ bib_number : chr [1:26598] "1" "3" "5" "19" ...
## $ half_time : chr [1:26598] "1H 2M 20S" "1H 2M 20S" "1H 2M 19S" "1H 2M 20S" ...
## $ finish_net : chr [1:26598] "2H 5M 54S" "2H 6M 4S" "2H 6M 6S" "2H 8M 1S" ...
## $ finish_gun : chr [1:26598] "2H 5M 54S" "2H 6M 4S" "2H 6M 6S" "2H 8M 1S" ...
## $ gender : chr [1:26598] "M" "M" "M" "M" ...
## $ half_time_sec : num [1:26598] 3740 3740 3739 3740 3740 ...
## $ finish_net_sec : num [1:26598] 7554 7564 7566 7681 7715 ...
## $ finish_gun_sec : num [1:26598] 7554 7564 7566 7681 7715 ...
## $ finish_net_minutes: num [1:26598] 126 126 126 128 129 ...
## - attr(*, "spec")=
## .. cols(
## .. age_group = col_character(),
## .. place_overall = col_double(),
## .. place_gender = col_double(),
## .. place_division = col_double(),
## .. name = col_character(),
## .. team = col_character(),
## .. bib_number = col_character(),
## .. half_time = col_character(),
## .. finish_net = col_character(),
## .. finish_gun = col_character(),
## .. gender = col_character(),
## .. half_time_sec = col_double(),
## .. finish_net_sec = col_double(),
## .. finish_gun_sec = col_double(),
## .. finish_net_minutes = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
head(boston_marathon_2023)
## # A tibble: 6 × 15
## age_group place_overall place_gender place_division name team bib_number
## <chr> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 18-39 1 1 1 Chebet, … Team– 1
## 2 18-39 2 2 2 Geay, Ga… Team– 3
## 3 18-39 3 3 3 Kipruto,… Team– 5
## 4 18-39 4 4 4 Korir, A… Team– 19
## 5 18-39 5 5 5 Talbi, Z… Team– 31
## 6 18-39 6 6 6 Kipchoge… Team– 2
## # ℹ 8 more variables: half_time <chr>, finish_net <chr>, finish_gun <chr>,
## # gender <chr>, half_time_sec <dbl>, finish_net_sec <dbl>,
## # finish_gun_sec <dbl>, finish_net_minutes <dbl>
missing_values <- colSums(is.na(boston_marathon_2023))
print(missing_values)
## age_group place_overall place_gender place_division
## 0 0 0 0
## name team bib_number half_time
## 0 0 0 72
## finish_net finish_gun gender half_time_sec
## 0 0 0 72
## finish_net_sec finish_gun_sec finish_net_minutes
## 0 0 0
data_types <- sapply(boston_marathon_2023, class)
print(data_types)
## age_group place_overall place_gender place_division
## "character" "numeric" "numeric" "numeric"
## name team bib_number half_time
## "character" "character" "character" "character"
## finish_net finish_gun gender half_time_sec
## "character" "character" "character" "numeric"
## finish_net_sec finish_gun_sec finish_net_minutes
## "numeric" "numeric" "numeric"
summary(boston_marathon_2023)
## age_group place_overall place_gender place_division
## Length:26598 Min. : 1 Min. : 1 Min. : 1
## Class :character 1st Qu.: 6656 1st Qu.: 3325 1st Qu.: 469
## Mode :character Median :13318 Median : 6650 Median :1085
## Mean :13315 Mean : 6783 Mean :1485
## 3rd Qu.:19972 3rd Qu.: 9975 3rd Qu.:2013
## Max. :26623 Max. :15176 Max. :5285
##
## name team bib_number half_time
## Length:26598 Length:26598 Length:26598 Length:26598
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## finish_net finish_gun gender half_time_sec
## Length:26598 Length:26598 Length:26598 Min. : 3739
## Class :character Class :character Class :character 1st Qu.: 5548
## Mode :character Mode :character Mode :character Median : 6213
## Mean : 6413
## 3rd Qu.: 7016
## Max. :12435
## NA's :72
## finish_net_sec finish_gun_sec finish_net_minutes
## Min. : 7554 Min. : 7554 Min. :125.9
## 1st Qu.:11464 1st Qu.:11584 1st Qu.:191.1
## Median :12836 Median :12998 Median :213.9
## Mean :13351 Mean :13527 Mean :222.5
## 3rd Qu.:14667 3rd Qu.:14914 3rd Qu.:244.4
## Max. :26431 Max. :26484 Max. :440.5
##
unique_values <- unique(boston_marathon_2023$age_group)
print(unique_values)
## [1] "18-39" "40-44" "45-49" "50-54" "55-59" "60-64" "65-69" "70-74" "75-79"
## [10] "80+"
data_types <- sapply(boston_marathon_2023, class)
print(data_types)
## age_group place_overall place_gender place_division
## "character" "numeric" "numeric" "numeric"
## name team bib_number half_time
## "character" "character" "character" "character"
## finish_net finish_gun gender half_time_sec
## "character" "character" "character" "numeric"
## finish_net_sec finish_gun_sec finish_net_minutes
## "numeric" "numeric" "numeric"
barplot(table(boston_marathon_2023$age_group),
main = "Distribution of Participant Age Groups",
xlab = "Age Group", ylab = "Frequency", col = "skyblue")
class(boston_marathon_2023$age_group)
## [1] "character"
summary(boston_marathon_2023$age_group)
## Length Class Mode
## 26598 character character
cleaned_data <- boston_marathon_2023[!is.na(boston_marathon_2023$age_group) & !is.nan(boston_marathon_2023$age_group), ]
summary(cleaned_data$age_group)
## Length Class Mode
## 26598 character character
barplot(table(boston_marathon_2023$age_group),
main = "Distribution of Participant Age Groups",
xlab = "Age Group", ylab = "Frequency", col = "skyblue")
barplot(table(boston_marathon_2023$age_group),
main = "Distribution of Participant Age Groups",
xlab = "Age Group", ylab = "Frequency", col = "skyblue")
summary(boston_marathon_2023$finish_net_sec)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 7554 11464 12836 13351 14667 26431
hist(boston_marathon_2023$finish_net_sec, main = "Distribution of Net Finishing Times",
xlab = "Net Finishing Time (seconds)", ylab = "Frequency", col = "skyblue")
# Create a scatter plot of net finishing time vs. gender
boston_marathon_2023$gender <- ifelse(boston_marathon_2023$gender == "W", "F", boston_marathon_2023$gender)
ggplot(boston_marathon_2023, aes(x = gender, y = finish_net_sec, fill = gender)) +
geom_violin(trim = FALSE) +
labs(title = "Net Finishing Time by Gender",
x = "Gender",
y = "Net Finishing Time (seconds)") +
scale_fill_manual(values = c("blue", "pink")) +
theme_minimal()
missing_gender <- sum(is.na(boston_marathon_2023$gender))
missing_finish_net_sec <- sum(is.na(boston_marathon_2023$finish_net_sec))
print(paste("Missing values in 'gender':", missing_gender))
## [1] "Missing values in 'gender': 0"
print(paste("Missing values in 'finish_net_sec':", missing_finish_net_sec))
## [1] "Missing values in 'finish_net_sec': 0"
boston_marathon_2023$finish_net_sec <- as.numeric(boston_marathon_2023$finish_net_sec)
ggplot(boston_marathon_2023, aes(x = gender, y = age_group, fill = gender)) +
geom_boxplot() +
labs(title = "Age Distribution by Gender", x = "Gender", y = "Age") +
scale_fill_manual(values = c("skyblue", "pink")) +
theme_minimal()
print(unique(boston_marathon_2023$gender))
## [1] "M" "F"
print(sum(is.na(boston_marathon_2023$gender)))
## [1] 0
print(sum(is.na(boston_marathon_2023$age_group)))
## [1] 0
str(boston_marathon_2023)
## spc_tbl_ [26,598 × 15] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ age_group : chr [1:26598] "18-39" "18-39" "18-39" "18-39" ...
## $ place_overall : num [1:26598] 1 2 3 4 5 6 7 8 9 10 ...
## $ place_gender : num [1:26598] 1 2 3 4 5 6 7 8 9 10 ...
## $ place_division : num [1:26598] 1 2 3 4 5 6 7 8 9 10 ...
## $ name : chr [1:26598] "Chebet, Evans" "Geay, Gabriel" "Kipruto, Benson" "Korir, Albert" ...
## $ team : chr [1:26598] "Team–" "Team–" "Team–" "Team–" ...
## $ bib_number : chr [1:26598] "1" "3" "5" "19" ...
## $ half_time : chr [1:26598] "1H 2M 20S" "1H 2M 20S" "1H 2M 19S" "1H 2M 20S" ...
## $ finish_net : chr [1:26598] "2H 5M 54S" "2H 6M 4S" "2H 6M 6S" "2H 8M 1S" ...
## $ finish_gun : chr [1:26598] "2H 5M 54S" "2H 6M 4S" "2H 6M 6S" "2H 8M 1S" ...
## $ gender : chr [1:26598] "M" "M" "M" "M" ...
## $ half_time_sec : num [1:26598] 3740 3740 3739 3740 3740 ...
## $ finish_net_sec : num [1:26598] 7554 7564 7566 7681 7715 ...
## $ finish_gun_sec : num [1:26598] 7554 7564 7566 7681 7715 ...
## $ finish_net_minutes: num [1:26598] 126 126 126 128 129 ...
## - attr(*, "spec")=
## .. cols(
## .. age_group = col_character(),
## .. place_overall = col_double(),
## .. place_gender = col_double(),
## .. place_division = col_double(),
## .. name = col_character(),
## .. team = col_character(),
## .. bib_number = col_character(),
## .. half_time = col_character(),
## .. finish_net = col_character(),
## .. finish_gun = col_character(),
## .. gender = col_character(),
## .. half_time_sec = col_double(),
## .. finish_net_sec = col_double(),
## .. finish_gun_sec = col_double(),
## .. finish_net_minutes = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
sum(is.na(boston_marathon_2023$age_group))
## [1] 0
str(boston_marathon_2023$age_group)
## chr [1:26598] "18-39" "18-39" "18-39" "18-39" "18-39" "18-39" "18-39" ...
boston_marathon_2023$numeric_age_group <- as.numeric(as.character(boston_marathon_2023$age_group))
## Warning: NAs introduced by coercion
str(boston_marathon_2023$numeric_age_group)
## num [1:26598] NA NA NA NA NA NA NA NA NA NA ...
ggplot(boston_marathon_2023, aes(x = gender, y = finish_net_sec)) +
geom_boxplot(aes(fill = gender), fill = c("skyblue", "pink")) +
labs(title = "Finish Time Distribution by Gender", x = "Gender", y = "Finish Time (seconds)") +
scale_fill_identity() + # Use identity scale for fill colors
theme_minimal()
male_finish_times <- boston_marathon_2023$finish_net_sec[boston_marathon_2023$gender == "M"]
female_finish_times <- boston_marathon_2023$finish_net_sec[boston_marathon_2023$gender == "W"]
length(male_finish_times)
## [1] 15175
length(female_finish_times)
## [1] 0
sum(is.na(male_finish_times))
## [1] 0
sum(is.na(female_finish_times))
## [1] 0
class(male_finish_times)
## [1] "numeric"
class(female_finish_times)
## [1] "numeric"
summary(male_finish_times)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 7554 10774 12056 12746 14024 26019
summary(female_finish_times)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
##
str(female_finish_times)
## num(0)
summary(female_finish_times)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
##
Test Statistic (t): The test statistic is approximately -45.517.
Degrees of Freedom (df): The degrees of freedom are approximately 25563.
P-value: The p-value is less than 2.2e-16, which is essentially zero. This indicates that the probability of observing the data, given that there is no difference in finish times between male and female participants, is extremely low.
Confidence Interval: The 95% confidence interval for the difference in means ranges from -1470.888 to -1349.438.
Since the p-value is significantly smaller than any reasonable significance level (such as 0.05), we reject the null hypothesis and conclude that there is a significant difference in finish times between male and female participants.the negative test statistic indicates that, on average, male participants tend to have shorter finish times compared to female participants.now i will visualizing the difference in finish times between male and female participants # Load the plotly library
library(plotly)
## Warning: package 'plotly' was built under R version 4.3.3
##
## 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
plot_ly(data = boston_marathon_2023, x = ~age_group, y = ~finish_net_sec, color = ~gender,
type = 'scatter', mode = 'markers', marker = list(size = 8)) %>%
layout(title = "Finish Time vs. Age (Interactive)",
xaxis = list(title = "Age"),
yaxis = list(title = "Finish Time (seconds)"),
hoverinfo = "text",
text = ~paste("Gender: ", gender))
## Warning in RColorBrewer::brewer.pal(N, "Set2"): minimal value for n is 3, returning requested palette with 3 different levels
## Warning in RColorBrewer::brewer.pal(N, "Set2"): minimal value for n is 3, returning requested palette with 3 different levels
## Warning: 'layout' objects don't have these attributes: 'hoverinfo', 'text'
## Valid attributes include:
## '_deprecated', 'activeshape', 'annotations', 'autosize', 'autotypenumbers', 'calendar', 'clickmode', 'coloraxis', 'colorscale', 'colorway', 'computed', 'datarevision', 'dragmode', 'editrevision', 'editType', 'font', 'geo', 'grid', 'height', 'hidesources', 'hoverdistance', 'hoverlabel', 'hovermode', 'images', 'legend', 'mapbox', 'margin', 'meta', 'metasrc', 'modebar', 'newshape', 'paper_bgcolor', 'plot_bgcolor', 'polar', 'scene', 'selectdirection', 'selectionrevision', 'separators', 'shapes', 'showlegend', 'sliders', 'smith', 'spikedistance', 'template', 'ternary', 'title', 'transition', 'uirevision', 'uniformtext', 'updatemenus', 'width', 'xaxis', 'yaxis', 'barmode', 'bargap', 'mapType'
The dataset was sourced from the provided link: Boston Marathon 2023 Dataset., I performed data cleaning to ensure its quality and integrity for analysis. This involved addressing missing values, checking for outliers, and formatting variables as needed. For example, I removed any incomplete rows with missing data points and ensured consistency in the formatting of categorical variables.
I chose this topic and dataset because marathon running is not only a popular sport but its interesting to me . Analyzing the data from an event like the Boston Marathon allows for insights into the demographics of participants, their performance, and potentially uncovering any disparities or interesting trends.
The Boston Marathon is one of the oldest marathons in the world, attracting elite athletes as well as amateur runners from around the globe. It was first held in 1897 and is held annually on Patriots’ Day, the third Monday of April, in Boston, Massachusetts, USA.
In recent years, the Boston Marathon has become a symbol of resilience and unity, particularly after the tragic bombings near the finish line in 2013. The event continues to draw thousands of participants and spectators each year, showcasing the spirit of community and determination.
One interesting pattern that emerged from the visualization is the general trend of older participants having longer finish times compared to younger participants. Additionally, there was a noticeable difference in finish times between male and female participants, with male participants tending to have shorter finish times on average.
While the visualization effectively captured the main relationship of interest, there could have been additional variables included for a more comprehensive analysis. For example, incorporating data on training mileage, weather conditions, or previous marathon experience could provide further insights into performance determinants.
Overall, the visualization explores the relationship between age, gender, and finish times in the Boston Marathon dataset, offering valuable insights into the demographics and performance of participants.