speed_data <- speed_data %>%
mutate(
measurement_tstamp = ymd_hms(measurement_tstamp),
month = month(measurement_tstamp),
month_name = month(measurement_tstamp, label = TRUE, abbr = FALSE),
day_name = wday(measurement_tstamp, label = TRUE, abbr = FALSE),
hour = hour(measurement_tstamp),
day_type = if_else(day_name %in% c("Saturday", "Sunday"), "Weekend", "Weekday"),
time_period = case_when(
hour >= 6 & hour < 9 ~ "Morning Peak",
hour >= 9 & hour < 16 ~ "Daytime",
hour >= 16 & hour < 20 ~ "Evening Peak",
TRUE ~ "Nighttime"
)
) %>%
mutate(
month_name = factor(
as.character(month_name),
levels = c("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December")
),
day_type = factor(day_type, levels = c("Weekday", "Weekend")),
time_period = factor(time_period, levels = c("Morning Peak", "Daytime", "Evening Peak", "Nighttime"))
)This report analyzes roadway speed time series data to examine how speed varies across months, day types, and time of day conditions using the dataset 3T_xd_18.csv. The preprocessing step converts timestamps into datetime format and extracts variables such as month, hour, and day of week. Observations are classified into weekday and weekend, and further grouped into four time periods: morning peak, daytime, evening peak, and nighttime. The analysis computes mean speed, standard deviation, and 85th percentile speed for each combination of month, day type, and time period, and presents the results using tables and visualizations to show overall speed patterns. Segment level grouping (xd_id) is not used in this analysis, as the focus is on aggregated trends across all roadway segments, which helps keep the results clear and allows consistent comparison of temporal patterns.
dataset_description <- tibble(
Item = c(
"Dataset Name",
"Number of Observations",
"Number of Unique Road Segments",
"Start Time",
"End Time"
),
Value = c(
"3T_xd_18.csv",
format(nrow(speed_data), big.mark = ","),
format(n_distinct(speed_data$xd_id), big.mark = ","),
as.character(min(speed_data$measurement_tstamp, na.rm = TRUE)),
as.character(max(speed_data$measurement_tstamp, na.rm = TRUE))
)
)
kable(dataset_description, align = c("l", "l"), caption = "Dataset description") %>%
kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed"))| Item | Value |
|---|---|
| Dataset Name | 3T_xd_18.csv |
| Number of Observations | 7,546,686 |
| Number of Unique Road Segments | 153 |
| Start Time | 2018-01-01 00:10:00 |
| End Time | 2018-12-31 23:50:00 |
column_description <- tibble(
Column = c(
"xd_id",
"measurement_tstamp",
"speed",
"average_speed",
"reference_speed",
"travel_time_seconds",
"confidence_score",
"cvalue"
),
Description = c(
"Unique roadway segment identifier",
"Timestamp of the speed observation",
"Observed speed at the timestamp",
"Reported average speed",
"Reference or free flow benchmark speed",
"Estimated segment travel time in seconds",
"Confidence level",
"Supplementary traffic performance "
)
)
kable(column_description, align = c("l", "l"), caption = "Column description") %>%
kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed"))| Column | Description |
|---|---|
| xd_id | Unique roadway segment identifier |
| measurement_tstamp | Timestamp of the speed observation |
| speed | Observed speed at the timestamp |
| average_speed | Reported average speed |
| reference_speed | Reference or free flow benchmark speed |
| travel_time_seconds | Estimated segment travel time in seconds |
| confidence_score | Confidence level |
| cvalue | Supplementary traffic performance |
summary_table <- speed_data %>%
group_by(month, month_name, day_type, time_period) %>%
summarise(
mean_speed = mean(speed, na.rm = TRUE),
std_speed = sd(speed, na.rm = TRUE),
p85_speed = quantile(speed, probs = 0.85, na.rm = TRUE, names = FALSE),
n_obs = n(),
.groups = "drop"
) %>%
arrange(month, day_type, time_period) %>%
mutate(
mean_speed = round(mean_speed, 2),
std_speed = round(std_speed, 2),
p85_speed = round(p85_speed, 2)
)
write.csv(summary_table, "summary_speed_by_month_daytype_timeperiod.csv", row.names = FALSE)
datatable(
summary_table,
caption = "Structured summary table of mean speed, standard deviation, 85th percentile speed, and number of observations",
options = list(pageLength = 12, scrollX = TRUE)
)monthly_summary <- speed_data %>%
group_by(month, month_name) %>%
summarise(
mean_speed = mean(speed, na.rm = TRUE),
std_speed = sd(speed, na.rm = TRUE),
p85_speed = quantile(speed, probs = 0.85, na.rm = TRUE, names = FALSE),
n_obs = n(),
.groups = "drop"
) %>%
arrange(month) %>%
mutate(
mean_speed = round(mean_speed, 2),
std_speed = round(std_speed, 2),
p85_speed = round(p85_speed, 2)
)
daytype_summary <- speed_data %>%
group_by(day_type) %>%
summarise(
mean_speed = mean(speed, na.rm = TRUE),
std_speed = sd(speed, na.rm = TRUE),
p85_speed = quantile(speed, probs = 0.85, na.rm = TRUE, names = FALSE),
n_obs = n(),
.groups = "drop"
) %>%
mutate(
mean_speed = round(mean_speed, 2),
std_speed = round(std_speed, 2),
p85_speed = round(p85_speed, 2)
)
timeperiod_summary <- speed_data %>%
group_by(time_period) %>%
summarise(
mean_speed = mean(speed, na.rm = TRUE),
std_speed = sd(speed, na.rm = TRUE),
p85_speed = quantile(speed, probs = 0.85, na.rm = TRUE, names = FALSE),
n_obs = n(),
.groups = "drop"
) %>%
mutate(
mean_speed = round(mean_speed, 2),
std_speed = round(std_speed, 2),
p85_speed = round(p85_speed, 2)
)
bar_summary <- speed_data %>%
group_by(day_type, time_period) %>%
summarise(
mean_speed = mean(speed, na.rm = TRUE),
p85_speed = quantile(speed, probs = 0.85, na.rm = TRUE, names = FALSE),
.groups = "drop"
) %>%
mutate(
mean_speed = round(mean_speed, 2),
p85_speed = round(p85_speed, 2)
)
write.csv(monthly_summary, "monthly_speed_summary.csv", row.names = FALSE)
write.csv(daytype_summary, "daytype_speed_summary.csv", row.names = FALSE)
write.csv(timeperiod_summary, "timeperiod_speed_summary.csv", row.names = FALSE)
write.csv(bar_summary, "mean_p85_by_daytype_timeperiod.csv", row.names = FALSE)plot_monthly <- ggplot(monthly_summary, aes(x = month, y = mean_speed, group = 1)) +
geom_line(color = "#1f4e79", linewidth = 1.2) +
geom_point(size = 3.2, color = "#2e8b57") +
geom_label(
aes(label = round(mean_speed, 2)),
size = 3.2,
fill = "white",
color = "black",
label.size = 0.15,
vjust = -0.8
) +
scale_x_continuous(
breaks = monthly_summary$month,
labels = monthly_summary$month_name
) +
labs(
title = "Visualization 1: Monthly Trend of Average Speed",
subtitle = "Average roadway speed by month across all roadway segments",
x = "Month",
y = "Average Speed"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 18),
plot.subtitle = element_text(size = 11),
axis.text.x = element_text(angle = 25, hjust = 1),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "white", color = NA),
plot.background = element_rect(fill = "white", color = NA)
)
plot_monthlyset.seed(123)
speed_sample_box <- speed_data %>%
select(speed, day_type, time_period) %>%
sample_n(min(250000, nrow(.)))
plot_box <- ggplot(speed_sample_box, aes(x = time_period, y = speed, fill = time_period)) +
geom_boxplot(outlier.alpha = 0.12, width = 0.72) +
facet_wrap(~day_type, ncol = 1) +
scale_fill_manual(values = c(
"Morning Peak" = "#8ecae6",
"Daytime" = "#b7e4c7",
"Evening Peak" = "#90be6d",
"Nighttime" = "#577590"
)) +
labs(
title = "Visualization 2: Boxplots by Day Type and Time Period",
subtitle = "Speed distributions under weekday and weekend conditions",
x = "Time Period",
y = "Speed",
fill = "Time Period"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 18),
plot.subtitle = element_text(size = 11),
axis.text.x = element_text(angle = 0, hjust = 0.5),
panel.grid.minor = element_blank(),
legend.position = "bottom",
strip.text = element_text(face = "bold", size = 12),
panel.background = element_rect(fill = "white", color = NA),
plot.background = element_rect(fill = "white", color = NA)
)
plot_boxbar_long <- bar_summary %>%
pivot_longer(
cols = c(mean_speed, p85_speed),
names_to = "metric",
values_to = "speed_value"
) %>%
mutate(
metric = factor(
metric,
levels = c("mean_speed", "p85_speed"),
labels = c("Mean Speed", "85th Percentile Speed")
)
)
plot_bar <- ggplot(bar_long, aes(x = time_period, y = speed_value, fill = metric)) +
geom_col(position = position_dodge(width = 0.75), width = 0.68) +
geom_text(
aes(label = round(speed_value, 2)),
position = position_dodge(width = 0.75),
vjust = -0.35,
size = 3.5
) +
facet_wrap(~day_type) +
scale_fill_manual(values = c(
"Mean Speed" = "#74c69d",
"85th Percentile Speed" = "#1d3557"
)) +
labs(
title = "Visualization 3: Mean Speed vs 85th Percentile Speed",
subtitle = "Comparison across time periods for weekday and weekend conditions",
x = "Time Period",
y = "Speed",
fill = "Metric"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 18),
plot.subtitle = element_text(size = 11),
axis.text.x = element_text(angle = 15, hjust = 1),
panel.grid.minor = element_blank(),
legend.position = "bottom",
strip.text = element_text(face = "bold", size = 12),
panel.background = element_rect(fill = "white", color = NA),
plot.background = element_rect(fill = "white", color = NA)
)
plot_barline_data <- speed_data %>%
group_by(month_name, time_period) %>%
summarise(mean_speed = mean(speed, na.rm = TRUE), .groups = "drop")
ggplot(line_data, aes(x = month_name, y = mean_speed, color = time_period, group = time_period)) +
geom_line(size = 1.2) +
geom_point(size = 2.5) +
labs(
title = "Monthly Speed Trend by Time Period",
x = "Month",
y = "Mean Speed",
color = "Time Period"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))ggplot(speed_data, aes(x = time_period, y = speed, fill = time_period)) +
geom_violin(alpha = 0.7) +
facet_wrap(~day_type) +
labs(
title = "Speed Distribution by Time Period and Day Type",
x = "Time Period",
y = "Speed"
) +
theme_minimal()line_compare_data <- speed_data %>%
group_by(day_type, time_period) %>%
summarise(
mean_speed = mean(speed, na.rm = TRUE),
p85_speed = quantile(speed, 0.85, na.rm = TRUE),
.groups = "drop"
) %>%
pivot_longer(
cols = c(mean_speed, p85_speed),
names_to = "metric",
values_to = "value"
)
ggplot(line_compare_data, aes(x = time_period, y = value, group = metric, color = metric)) +
geom_line(size = 1.2) +
geom_point(size = 3) +
facet_wrap(~day_type) +
labs(
title = "Comparison of Mean and 85th Percentile Speed",
x = "Time Period",
y = "Speed",
color = "Metric"
) +
scale_color_manual(values = c("mean_speed" = "#1f4e79", "p85_speed" = "#2e8b57"),
labels = c("Mean Speed", "85th Percentile Speed")) +
theme_minimal()# Safer extraction of monthly extremes
highest_month <- monthly_summary %>%
filter(!is.na(month_name)) %>%
slice_max(order_by = mean_speed, n = 1, with_ties = FALSE)
lowest_month <- monthly_summary %>%
filter(!is.na(month_name)) %>%
slice_min(order_by = mean_speed, n = 1, with_ties = FALSE)
# Highest variability period
highest_variability_period <- timeperiod_summary %>%
slice_max(order_by = std_speed, n = 1, with_ties = FALSE)
# Weekday and weekend means
weekday_mean <- daytype_summary %>%
filter(day_type == "Weekday") %>%
pull(mean_speed)
weekend_mean <- daytype_summary %>%
filter(day_type == "Weekend") %>%
pull(mean_speed)
# Peak and off peak mean speeds
peak_summary <- bar_summary %>%
filter(time_period %in% c("Morning Peak", "Evening Peak")) %>%
summarise(avg_peak_mean = mean(mean_speed), .groups = "drop")
offpeak_summary <- bar_summary %>%
filter(time_period %in% c("Daytime", "Nighttime")) %>%
summarise(avg_offpeak_mean = mean(mean_speed), .groups = "drop")
# Largest mean vs p85 gap
largest_gap <- bar_summary %>%
mutate(gap = p85_speed - mean_speed) %>%
slice_max(order_by = gap, n = 1, with_ties = FALSE)
cat(paste0(
"<h3>Interpretation of Results</h3>",
"<p><b>How does average speed vary across months? Are there seasonal patterns?</b> ",
"The monthly trend shows only moderate variation in average speed across the year. ",
"The highest monthly average speed is observed in <b>", as.character(highest_month$month_name), "</b> (",
round(highest_month$mean_speed, 2), "), while the lowest is observed in <b>",
as.character(lowest_month$month_name), "</b> (", round(lowest_month$mean_speed, 2), "). ",
"This indicates that month to month changes exist, but the overall annual pattern is fairly stable rather than sharply seasonal. ",
"The limited spread between the highest and lowest monthly averages suggests that time of day and traffic demand conditions likely have a stronger effect on speed than month alone.</p>",
"<p><b>Which time period shows the highest variability in speed?</b> ",
"The highest variability is observed during <b>", as.character(highest_variability_period$time_period), "</b>, ",
"with a standard deviation of <b>", round(highest_variability_period$std_speed, 2), "</b>. ",
"A higher standard deviation indicates that speeds are more dispersed, which means traffic flow is less uniform during this period. ",
"This is consistent with unstable operating conditions, where congestion buildup, speed changes, and mixed driver behavior are more common.</p>",
"<p><b>How do weekday and weekend speed patterns differ?</b> ",
"The average speed on weekdays is <b>", round(weekday_mean, 2), "</b>, whereas the average speed on weekends is <b>",
round(weekend_mean, 2), "</b>. ",
ifelse(
weekend_mean > weekday_mean,
"This shows that traffic generally moves faster on weekends than on weekdays. A likely reason is lower commuter demand and reduced recurring congestion on weekends.",
"This shows that weekday traffic moves slightly faster than weekend traffic in this dataset, which may reflect local travel patterns or corridor specific demand conditions."
),
"</p>",
"<p><b>Are peak periods associated with lower or higher speeds compared to off peak periods?</b> ",
"The average mean speed across peak periods is <b>", round(peak_summary$avg_peak_mean, 2), "</b>, compared with <b>",
round(offpeak_summary$avg_offpeak_mean, 2), "</b> during off peak periods. ",
"This confirms that peak periods are associated with lower operating speeds. ",
"This result is expected because morning and evening peak periods typically experience higher traffic demand, which reduces traffic flow efficiency and lowers speeds.</p>",
"<p><b>How does the 85th percentile speed compare to the mean across different conditions?</b> ",
"Across all grouped conditions, the 85th percentile speed remains higher than the mean speed. ",
"The largest difference is found for <b>", as.character(largest_gap$day_type), " - ",
as.character(largest_gap$time_period), "</b>, where the gap is <b>", round(largest_gap$gap, 2), "</b>. ",
"This shows that a portion of vehicles travel notably faster than the average traffic stream. ",
"From a traffic engineering perspective, this gap reflects speed dispersion, which is important because larger speed differences within the traffic stream can increase operational conflict and safety concern.</p>",
"<p><b>What are the implications of these patterns for speed management and roadway safety?</b> ",
"The results show that time of day and day type have a clear effect on roadway speed patterns. ",
"Peak periods are associated with lower average speeds and greater instability, while off peak and weekend conditions support higher speeds. ",
"Although higher speeds may reflect better mobility, higher upper percentile speeds may also indicate greater speeding potential. ",
"These findings are useful for identifying when speed management, enforcement, and roadway monitoring may be most needed.</p>"
))How does average speed vary across months? Are there seasonal patterns? The monthly trend shows only moderate variation in average speed across the year. The highest monthly average speed is observed in January (42.98), while the lowest is observed in October (42.14). This indicates that month to month changes exist, but the overall annual pattern is fairly stable rather than sharply seasonal. The limited spread between the highest and lowest monthly averages suggests that time of day and traffic demand conditions likely have a stronger effect on speed than month alone.
Which time period shows the highest variability in speed? The highest variability is observed during Evening Peak, with a standard deviation of 11.82. A higher standard deviation indicates that speeds are more dispersed, which means traffic flow is less uniform during this period. This is consistent with unstable operating conditions, where congestion buildup, speed changes, and mixed driver behavior are more common.
How do weekday and weekend speed patterns differ? The average speed on weekdays is 42.28, whereas the average speed on weekends is 43.08. This shows that traffic generally moves faster on weekends than on weekdays. A likely reason is lower commuter demand and reduced recurring congestion on weekends.
Are peak periods associated with lower or higher speeds compared to off peak periods? The average mean speed across peak periods is 42.1, compared with 42.8 during off peak periods. This confirms that peak periods are associated with lower operating speeds. This result is expected because morning and evening peak periods typically experience higher traffic demand, which reduces traffic flow efficiency and lowers speeds.
How does the 85th percentile speed compare to the mean across different conditions? Across all grouped conditions, the 85th percentile speed remains higher than the mean speed. The largest difference is found for Weekday - Morning Peak, where the gap is 12.84. This shows that a portion of vehicles travel notably faster than the average traffic stream. From a traffic engineering perspective, this gap reflects speed dispersion, which is important because larger speed differences within the traffic stream can increase operational conflict and safety concern.
What are the implications of these patterns for speed management and roadway safety? The results show that time of day and day type have a clear effect on roadway speed patterns. Peak periods are associated with lower average speeds and greater instability, while off peak and weekend conditions support higher speeds. Although higher speeds may reflect better mobility, higher upper percentile speeds may also indicate greater speeding potential. These findings are useful for identifying when speed management, enforcement, and roadway monitoring may be most needed.
# Data for monthly trend by time period
line_data_interpret <- speed_data %>%
group_by(month_name, time_period) %>%
summarise(mean_speed = mean(speed, na.rm = TRUE), .groups = "drop")
# Highest and lowest monthly speeds across all time periods
highest_line <- line_data_interpret %>%
slice_max(order_by = mean_speed, n = 1, with_ties = FALSE)
lowest_line <- line_data_interpret %>%
slice_min(order_by = mean_speed, n = 1, with_ties = FALSE)
# Average speed by time period
time_period_avg <- line_data_interpret %>%
group_by(time_period) %>%
summarise(avg_speed = mean(mean_speed), .groups = "drop")
highest_time_period <- time_period_avg %>%
slice_max(order_by = avg_speed, n = 1, with_ties = FALSE)
lowest_time_period <- time_period_avg %>%
slice_min(order_by = avg_speed, n = 1, with_ties = FALSE)
# Speed variability using standard deviation directly from grouped summary
highest_variability_period <- timeperiod_summary %>%
slice_max(order_by = std_speed, n = 1, with_ties = FALSE)
# Weekday and weekend mean speeds
weekday_mean <- daytype_summary %>%
filter(day_type == "Weekday") %>%
pull(mean_speed)
weekend_mean <- daytype_summary %>%
filter(day_type == "Weekend") %>%
pull(mean_speed)
# Mean vs 85th percentile comparison
line_compare_data <- speed_data %>%
group_by(day_type, time_period) %>%
summarise(
mean_speed = mean(speed, na.rm = TRUE),
p85_speed = quantile(speed, 0.85, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(gap = p85_speed - mean_speed)
largest_gap <- line_compare_data %>%
slice_max(order_by = gap, n = 1, with_ties = FALSE)
avg_gap <- mean(line_compare_data$gap, na.rm = TRUE)
# Peak and off peak comparison
peak_mean <- line_compare_data %>%
filter(time_period %in% c("Morning Peak", "Evening Peak")) %>%
summarise(value = mean(mean_speed), .groups = "drop") %>%
pull(value)
offpeak_mean <- line_compare_data %>%
filter(time_period %in% c("Daytime", "Nighttime")) %>%
summarise(value = mean(mean_speed), .groups = "drop") %>%
pull(value)
cat(paste0(
"<h3>Additional Interpretation from Additional Visualizations</h3>",
"<p><b>Monthly variation and seasonal pattern.</b> The multi-line plot shows that average speed changes moderately across months, but the variation is not large enough to indicate a strong seasonal pattern. ",
"The highest average speed is observed in <b>", as.character(highest_line$month_name), "</b> during <b>", as.character(highest_line$time_period), "</b> (",
round(highest_line$mean_speed, 2), "), while the lowest is observed in <b>", as.character(lowest_line$month_name), "</b> during <b>",
as.character(lowest_line$time_period), "</b> (", round(lowest_line$mean_speed, 2), "). ",
"This suggests that monthly effects exist, but time of day has a stronger influence on roadway speed than month alone.</p>",
"<p><b>Time period with the highest variability.</b> The violin plot and grouped summary both indicate that <b>",
as.character(highest_variability_period$time_period), "</b> has the highest variability, with a standard deviation of <b>",
round(highest_variability_period$std_speed, 2), "</b>. ",
"The wider spread of the violin shape during this period shows that traffic flow is less uniform, which is consistent with unstable operating conditions and changing congestion levels.</p>",
"<p><b>Weekday versus weekend speed patterns.</b> The violin plot shows that weekend speeds are slightly shifted toward higher values compared with weekdays. ",
"This is supported by the summary results, where the average weekday speed is <b>", round(weekday_mean, 2), "</b> and the average weekend speed is <b>",
round(weekend_mean, 2), "</b>. ",
ifelse(
weekend_mean > weekday_mean,
"This indicates that traffic generally moves faster on weekends, likely due to lower commuter demand and reduced recurring congestion.",
"This indicates that weekday traffic is slightly faster in this dataset, which may reflect local travel demand patterns."
),
"</p>",
"<p><b>Peak versus off peak conditions.</b> The multi-line plot clearly shows that nighttime remains the highest speed condition across the year, while peak periods remain lower. ",
"The average mean speed across peak periods is <b>", round(peak_mean, 2), "</b>, compared with <b>", round(offpeak_mean, 2), "</b> during off peak periods. ",
"This confirms that peak periods are associated with lower operating speeds, while off peak periods support faster traffic flow because demand is less concentrated.</p>",
"<p><b>Comparison of mean speed and 85th percentile speed.</b> The line comparison plot shows that the 85th percentile speed is consistently higher than the mean speed across all conditions. ",
"On average, the gap between the two measures is <b>", round(avg_gap, 2), "</b>. ",
"The largest gap is observed for <b>", as.character(largest_gap$day_type), " - ", as.character(largest_gap$time_period), "</b>, where the difference is <b>",
round(largest_gap$gap, 2), "</b>. ",
"This indicates that a portion of vehicles travel noticeably faster than the average traffic stream, which reflects speed dispersion within the traffic flow.</p>",
"<p><b>Implications for speed management and roadway safety.</b> The additional visualizations show that time period is the dominant factor shaping speed behavior, with nighttime producing the highest speeds and peak periods producing lower and more variable speeds. ",
"The wider speed distributions during congested periods and the persistent gap between mean speed and 85th percentile speed suggest that both speed instability and speed differentials should be considered in traffic operations and safety planning. ",
"These findings support the need for time sensitive speed management, targeted monitoring during unstable periods, and greater attention to higher speed behavior during lower demand conditions.</p>"
))Monthly variation and seasonal pattern. The multi-line plot shows that average speed changes moderately across months, but the variation is not large enough to indicate a strong seasonal pattern. The highest average speed is observed in March during Nighttime (43.83), while the lowest is observed in October during Evening Peak (41). This suggests that monthly effects exist, but time of day has a stronger influence on roadway speed than month alone.
Time period with the highest variability. The violin plot and grouped summary both indicate that Evening Peak has the highest variability, with a standard deviation of 11.82. The wider spread of the violin shape during this period shows that traffic flow is less uniform, which is consistent with unstable operating conditions and changing congestion levels.
Weekday versus weekend speed patterns. The violin plot shows that weekend speeds are slightly shifted toward higher values compared with weekdays. This is supported by the summary results, where the average weekday speed is 42.28 and the average weekend speed is 43.08. This indicates that traffic generally moves faster on weekends, likely due to lower commuter demand and reduced recurring congestion.
Peak versus off peak conditions. The multi-line plot clearly shows that nighttime remains the highest speed condition across the year, while peak periods remain lower. The average mean speed across peak periods is 42.1, compared with 42.8 during off peak periods. This confirms that peak periods are associated with lower operating speeds, while off peak periods support faster traffic flow because demand is less concentrated.
Comparison of mean speed and 85th percentile speed. The line comparison plot shows that the 85th percentile speed is consistently higher than the mean speed across all conditions. On average, the gap between the two measures is 11.6. The largest gap is observed for Weekday - Morning Peak, where the difference is 12.84. This indicates that a portion of vehicles travel noticeably faster than the average traffic stream, which reflects speed dispersion within the traffic flow.
Implications for speed management and roadway safety. The additional visualizations show that time period is the dominant factor shaping speed behavior, with nighttime producing the highest speeds and peak periods producing lower and more variable speeds. The wider speed distributions during congested periods and the persistent gap between mean speed and 85th percentile speed suggest that both speed instability and speed differentials should be considered in traffic operations and safety planning. These findings support the need for time sensitive speed management, targeted monitoring during unstable periods, and greater attention to higher speed behavior during lower demand conditions.
The following files are automatically saved in the working directory during knitting:
summary_speed_by_month_daytype_timeperiod.csvmonthly_speed_summary.csvdaytype_speed_summary.csvtimeperiod_speed_summary.csvmean_p85_by_daytype_timeperiod.csvvisualization_1_monthly_trend_average_speed.pngvisualization_2_boxplots_daytype_timeperiod.pngvisualization_3_mean_vs_p85_speed.pngThis analysis shows that roadway speed varies across months, day types, and time periods. Monthly variation is limited, indicating stable annual patterns, while time of day has a stronger effect, with lower speeds and higher variability during peak periods and higher speeds during off peak periods. Weekend speeds are generally higher than weekday speeds, reflecting lower congestion. The consistent gap between mean and 85th percentile speeds indicates speed dispersion within the traffic stream. These findings are useful for traffic performance assessment and speed management planning.