在 R 中按日期高效查找的最佳数据结构
Best data structure for efficient look-up by date in R
我有一个数据框 df,其中包含 2018 年每小时通过伦敦地铁站的交通量:
Year Month Day Hour Station.ID Traffic
1 2018 1 1 0 A 1000
2 2018 1 1 0 B 1300
3 2018 1 1 0 C 956
4 2018 1 1 0 D 721
...
超过 7,000,000 行。我想要一种有效的方法来查找特定日期和时间的流量。例如,如果我想知道 2018 年 4 月 5 日上午 10 点 'X' 车站的交通情况,我目前会执行:
df[df$Year==2018 & df$Month==5 & df$Day==4 & df$Hour==10 & df$Station.ID=='X',]$Traffic
但是这种方法会不必要地查看整个数据帧。我的想法是将数据组织成这样的层次结构:
library(data.tree)
df$pathString <- paste("MyTree",
df$Year,
df$Month,
df$Day,
df$Hour,
df$Station.ID,
sep = "/")
dftree <- as.Node(df)
我之前的请求现在类似于:
dftree$'2018'$'5'$'4'$'10'$X$Traffic
这会快几个数量级。我的问题是首先将 df 实际组织成树需要太长时间!如果我取 1000 行的子集,则需要几分钟。它有 7,000,000 行,没有尽头。
我的问题:
1) 当数据按日期组织时,快速查找最合适的数据结构是什么?
2) df 是否太大不适合这个结构?
一个data.table
.
使用 flights
数据集,像您这样的查询大约需要半秒:
library(data.table)
library(nycflights13)
flights <- as.data.table(flights)
flights7M <- rbindlist(lapply(1:22, function(x) flights))
nrow(flights7M) / 7e6 # close enough
#> [1] 1.058439
bench::system_time({
setkey(flights7M, year, month, day, hour, origin)
flights7M[.(2013L, 5L, 4L, 10L, "JFK")]
})
#> process real
#> 1.8s 587.4ms
由 reprex package (v0.2.0) 创建于 2018-07-02。
我有一个数据框 df,其中包含 2018 年每小时通过伦敦地铁站的交通量:
Year Month Day Hour Station.ID Traffic
1 2018 1 1 0 A 1000
2 2018 1 1 0 B 1300
3 2018 1 1 0 C 956
4 2018 1 1 0 D 721
...
超过 7,000,000 行。我想要一种有效的方法来查找特定日期和时间的流量。例如,如果我想知道 2018 年 4 月 5 日上午 10 点 'X' 车站的交通情况,我目前会执行:
df[df$Year==2018 & df$Month==5 & df$Day==4 & df$Hour==10 & df$Station.ID=='X',]$Traffic
但是这种方法会不必要地查看整个数据帧。我的想法是将数据组织成这样的层次结构:
library(data.tree)
df$pathString <- paste("MyTree",
df$Year,
df$Month,
df$Day,
df$Hour,
df$Station.ID,
sep = "/")
dftree <- as.Node(df)
我之前的请求现在类似于:
dftree$'2018'$'5'$'4'$'10'$X$Traffic
这会快几个数量级。我的问题是首先将 df 实际组织成树需要太长时间!如果我取 1000 行的子集,则需要几分钟。它有 7,000,000 行,没有尽头。
我的问题:
1) 当数据按日期组织时,快速查找最合适的数据结构是什么?
2) df 是否太大不适合这个结构?
一个data.table
.
使用 flights
数据集,像您这样的查询大约需要半秒:
library(data.table)
library(nycflights13)
flights <- as.data.table(flights)
flights7M <- rbindlist(lapply(1:22, function(x) flights))
nrow(flights7M) / 7e6 # close enough
#> [1] 1.058439
bench::system_time({
setkey(flights7M, year, month, day, hour, origin)
flights7M[.(2013L, 5L, 4L, 10L, "JFK")]
})
#> process real
#> 1.8s 587.4ms
由 reprex package (v0.2.0) 创建于 2018-07-02。