使用 ggplot2 在多个日期按工作日和小时绘制平均观察计数
Plotting average observation counts by weekday and hour across multiple dates using ggplot2
我有一个数据框,其中每个观察表示都是我使用 OpenCV 计算的现实世界中的一个对象。经过一些突变并使用 tidyverse 和 lubridate 我的数据框看起来像这样:
> head(odcCountsRoadUsers)
frameId objectClass dayOfWeek ymdhms hourOfDay
1 1133 car 1 2021-12-05 13:45:25 13
2 1159 car 1 2021-12-05 13:45:26 13
3 1243 car 1 2021-12-05 13:45:31 13
4 1280 person 1 2021-12-05 13:45:33 13
5 1305 bus 1 2021-12-05 13:45:34 13
6 1812 person 1 2021-12-05 13:46:03 13
我有多天的数据,还包含同一 dayOfWeek
的多个计数。我想要做的是为一周中的每一天(总共 7 个)创建一个直方图,其中包含一天中每个小时的观察次数。结果应类似于此(一周中每天一个直方图):
我的问题是:
- 我如何使用 ggplot2 以便它使用 POSIXct
ymdhms
作为 x 轴,对于 y 轴通过 hourOfDay
(或直接使用 ymdhms
如果可能的话)并按 dayOfWeek
? 过滤
- 因为我有好几天的记录,所以我只想要
dayOfWeek
的平均值,而不是简单地将不同日期的所有观察值的计数加在一起。我怎样才能有效地做到这一点?在绘图之前为此创建一个单独的数据框是否有意义,或者可以使用 ggplot2
轻松完成?
关于 objectClass
有机会 separate/group 的额外问题,但这两个是我自己似乎无法弄清楚的最紧迫的问题。
source data is available on GitHub 如果有帮助的话。
你可以总结一下,例如使用 dplyr
包在给定小时内的所有星期一。在求和之后,x 轴只是一个从 0 到 23 的数字,它不再是表示特定、明确时间点的 POSIXct 类型。
library(tidyverse)
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
data <-
"https://raw.githubusercontent.com/yauh/opendatacam-statistics/main/input/counterData-2022-01-23-61ed51ecae46bd0088feb8f5.csv" %>%
read_csv(col_names = FALSE) %>%
transmute(
frameId = X1,
objectClass = X4,
time = X2
)
#>
#> ── Column specification ────────────────────────────────────────────────────────
#> cols(
#> X1 = col_double(),
#> X2 = col_datetime(format = ""),
#> X3 = col_character(),
#> X4 = col_character(),
#> X5 = col_double(),
#> X6 = col_double(),
#> X7 = col_character(),
#> X8 = col_double()
#> )
data
#> # A tibble: 77,966 × 3
#> frameId objectClass time
#> <dbl> <chr> <dttm>
#> 1 6369 person 2022-01-23 13:02:37
#> 2 6457 car 2022-01-23 13:02:42
#> 3 6494 car 2022-01-23 13:02:45
#> 4 6583 car 2022-01-23 13:02:51
#> 5 6587 car 2022-01-23 13:02:51
#> 6 6767 car 2022-01-23 13:03:03
#> 7 6926 car 2022-01-23 13:03:14
#> 8 7201 car 2022-01-23 13:03:32
#> 9 7237 car 2022-01-23 13:03:35
#> 10 7409 car 2022-01-23 13:03:46
#> # … with 77,956 more rows
aggregated_data <-
data %>%
mutate(
weekday = wday(time, label = TRUE),
hour = hour(time),
date = date(time)
) %>%
count(weekday, date, hour) %>%
# average e.g over all mondays
group_by(weekday, hour) %>%
summarise(n = mean(n))
#> `summarise()` has grouped output by 'weekday'. You can override using the
#> `.groups` argument.
aggregated_data
#> # A tibble: 168 × 3
#> # Groups: weekday [7]
#> weekday hour n
#> <ord> <int> <dbl>
#> 1 Sun 0 29
#> 2 Sun 1 17
#> 3 Sun 2 17
#> 4 Sun 3 13
#> 5 Sun 4 44
#> 6 Sun 5 29
#> 7 Sun 6 47
#> 8 Sun 7 103
#> 9 Sun 8 245
#> 10 Sun 9 362
#> # … with 158 more rows
aggregated_data %>%
ggplot(aes(hour, n)) +
geom_col() +
facet_wrap(~weekday)
由 reprex package (v2.0.0)
于 2022-05-20 创建
如果您想比较每个工作日的差异,将它们绘制在一起也是个好主意:
aggregated_data %>%
ggplot(aes(hour, n, color = weekday)) +
geom_line()
添加对象 class 作为 group_by
的参数允许我们进行额外的分层:
aggregated_data2 <-
data %>%
mutate(
weekday = wday(time, label = TRUE),
hour = hour(time),
date = date(time)
) %>%
count(objectClass, weekday, date, hour) %>%
# average e.g over all mondays for each object class
group_by(objectClass, weekday, hour) %>%
summarise(n = mean(n))
aggregated_data2 %>%
ggplot(aes(hour, n, color = objectClass)) +
geom_line() +
facet_wrap(~weekday, scales = "free")
我有一个数据框,其中每个观察表示都是我使用 OpenCV 计算的现实世界中的一个对象。经过一些突变并使用 tidyverse 和 lubridate 我的数据框看起来像这样:
> head(odcCountsRoadUsers)
frameId objectClass dayOfWeek ymdhms hourOfDay
1 1133 car 1 2021-12-05 13:45:25 13
2 1159 car 1 2021-12-05 13:45:26 13
3 1243 car 1 2021-12-05 13:45:31 13
4 1280 person 1 2021-12-05 13:45:33 13
5 1305 bus 1 2021-12-05 13:45:34 13
6 1812 person 1 2021-12-05 13:46:03 13
我有多天的数据,还包含同一 dayOfWeek
的多个计数。我想要做的是为一周中的每一天(总共 7 个)创建一个直方图,其中包含一天中每个小时的观察次数。结果应类似于此(一周中每天一个直方图):
我的问题是:
- 我如何使用 ggplot2 以便它使用 POSIXct
ymdhms
作为 x 轴,对于 y 轴通过hourOfDay
(或直接使用ymdhms
如果可能的话)并按dayOfWeek
? 过滤
- 因为我有好几天的记录,所以我只想要
dayOfWeek
的平均值,而不是简单地将不同日期的所有观察值的计数加在一起。我怎样才能有效地做到这一点?在绘图之前为此创建一个单独的数据框是否有意义,或者可以使用ggplot2
轻松完成?
关于 objectClass
有机会 separate/group 的额外问题,但这两个是我自己似乎无法弄清楚的最紧迫的问题。
source data is available on GitHub 如果有帮助的话。
你可以总结一下,例如使用 dplyr
包在给定小时内的所有星期一。在求和之后,x 轴只是一个从 0 到 23 的数字,它不再是表示特定、明确时间点的 POSIXct 类型。
library(tidyverse)
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
data <-
"https://raw.githubusercontent.com/yauh/opendatacam-statistics/main/input/counterData-2022-01-23-61ed51ecae46bd0088feb8f5.csv" %>%
read_csv(col_names = FALSE) %>%
transmute(
frameId = X1,
objectClass = X4,
time = X2
)
#>
#> ── Column specification ────────────────────────────────────────────────────────
#> cols(
#> X1 = col_double(),
#> X2 = col_datetime(format = ""),
#> X3 = col_character(),
#> X4 = col_character(),
#> X5 = col_double(),
#> X6 = col_double(),
#> X7 = col_character(),
#> X8 = col_double()
#> )
data
#> # A tibble: 77,966 × 3
#> frameId objectClass time
#> <dbl> <chr> <dttm>
#> 1 6369 person 2022-01-23 13:02:37
#> 2 6457 car 2022-01-23 13:02:42
#> 3 6494 car 2022-01-23 13:02:45
#> 4 6583 car 2022-01-23 13:02:51
#> 5 6587 car 2022-01-23 13:02:51
#> 6 6767 car 2022-01-23 13:03:03
#> 7 6926 car 2022-01-23 13:03:14
#> 8 7201 car 2022-01-23 13:03:32
#> 9 7237 car 2022-01-23 13:03:35
#> 10 7409 car 2022-01-23 13:03:46
#> # … with 77,956 more rows
aggregated_data <-
data %>%
mutate(
weekday = wday(time, label = TRUE),
hour = hour(time),
date = date(time)
) %>%
count(weekday, date, hour) %>%
# average e.g over all mondays
group_by(weekday, hour) %>%
summarise(n = mean(n))
#> `summarise()` has grouped output by 'weekday'. You can override using the
#> `.groups` argument.
aggregated_data
#> # A tibble: 168 × 3
#> # Groups: weekday [7]
#> weekday hour n
#> <ord> <int> <dbl>
#> 1 Sun 0 29
#> 2 Sun 1 17
#> 3 Sun 2 17
#> 4 Sun 3 13
#> 5 Sun 4 44
#> 6 Sun 5 29
#> 7 Sun 6 47
#> 8 Sun 7 103
#> 9 Sun 8 245
#> 10 Sun 9 362
#> # … with 158 more rows
aggregated_data %>%
ggplot(aes(hour, n)) +
geom_col() +
facet_wrap(~weekday)
由 reprex package (v2.0.0)
于 2022-05-20 创建如果您想比较每个工作日的差异,将它们绘制在一起也是个好主意:
aggregated_data %>%
ggplot(aes(hour, n, color = weekday)) +
geom_line()
添加对象 class 作为 group_by
的参数允许我们进行额外的分层:
aggregated_data2 <-
data %>%
mutate(
weekday = wday(time, label = TRUE),
hour = hour(time),
date = date(time)
) %>%
count(objectClass, weekday, date, hour) %>%
# average e.g over all mondays for each object class
group_by(objectClass, weekday, hour) %>%
summarise(n = mean(n))
aggregated_data2 %>%
ggplot(aes(hour, n, color = objectClass)) +
geom_line() +
facet_wrap(~weekday, scales = "free")