The bins are centred. The data is at 0, 1, 2,..23, and so the bars are plotted such that they are centred over those values. If you really want them to start at 0, then do your own summary of the data and just add 0.5 to x when plotting.
Inspection of the summary data shows that the maximum is ~17000 at x = 0, not >20000.
library(tidyverse)
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
library(dslabs)
library(crimedata)
#> Warning: package 'crimedata' was built under R version 4.0.5
crime <- crimedata::get_crime_data(years = 2008:2018)
write.csv(crime, file = 'crime.csv')
crime20 <- crime # renaming for clarity - it is not the whole data set
# Exploring hourly reporting
crime20_hour <- crime20 %>%
mutate(hour = hour(date_single))
summary <-
crime20_hour %>%
group_by(hour) %>%
summarise(count = n()) %>%
ungroup()
#> `summarise()` ungrouping output (override with `.groups` argument)
summary %>%
ggplot(aes(x = hour+0.5, y = count))+
geom_col(fill="grey", width = 1)

summary
#> # A tibble: 24 x 2
#> hour count
#> <int> <int>
#> 1 0 17623
#> 2 1 7025
#> 3 2 6073
#> 4 3 5062
#> 5 4 4159
#> 6 5 3239
#> 7 6 3395
#> 8 7 4292
#> 9 8 6202
#> 10 9 6578
#> # ... with 14 more rows
Created on 2021-04-09 by the reprex package (v1.0.0)