如何按特定时间单位对含非规则时间戳的tibble列做滞后处理?
基于规则时间偏移的非规则时间序列滞后处理
我有一个包含非规则时间戳的tibble,希望基于规则时间偏移(如1天、3小时等)对另一列执行滞后处理,若对应偏移后的时间戳不存在,返回NA即可。
我已经自行编写了如下函数实现该功能,但想了解{lubridate}或其他R包是否有经过充分测试的成熟解决方案,而非我这种自行编写的实现。我认为当前方案可行,但想确认是否存在知名包提供的标准方案,或是更优的实现方式。
自行实现的解决方案
library(lubridate) library(dplyr) # 按指定时间单位和偏移量实现滞后的函数 # ts: 时间戳向量 # v: 与ts对应的数值向量,长度一致 # unit: 时间单位,如"hour"或"day" # unit_val: 偏移量,可正可负 lag_ts <- function(ts, v, unit, unit_val=1) { lookup_df <- tibble(ts, v, ts_lag = ts + do.call(unit, list(unit_val))) lookup_df |> select(ts) |> left_join(lookup_df |> select(ts=ts_lag, v) , "ts") |> pull("v") } # 测试:按1天滞后 tibble(ts=ymd_hms("2023-04-12T00:00:00") + hours(seq(1,48,8)) , v=lag_ts(ymd_hms("2023-04-12T00:00:00") + hours(seq(1,48,8)) , 1:6 , "days" , 1)) |> print()
运行结果:
# A tibble: 6 × 2 ts v <dttm> <int> 1 2023-04-12 01:00:00 NA 2 2023-04-12 09:00:00 NA 3 2023-04-12 17:00:00 NA 4 2023-04-13 01:00:00 1 5 2023-04-13 09:00:00 2 6 2023-04-13 17:00:00 3
成熟替代方案
1. 使用{tsibble}包(推荐)
{tsibble}是专为时间序列数据设计的tidyverse兼容包,它的lag()函数原生支持按时间单位指定滞后偏移,无需手动处理时间匹配,完美适配非规则时间序列,且经过广泛测试。
示例代码:
library(tsibble) library(lubridate) library(dplyr) # 构造测试数据并转换为tsibble(标记时间索引) df <- tibble( ts = ymd_hms("2023-04-12T00:00:00") + hours(seq(1,48,8)), v = 1:6 ) %>% as_tsibble(index = ts) # 按1天滞后,自动匹配时间戳,无匹配则返回NA df %>% mutate(v_lag = lag(v, days(1)))
运行结果和自行实现的完全一致,但代码更简洁直观,且内置了时间序列的相关校验。
2. 使用{data.table}的滚动连接
如果处理大规模数据,{data.table}的滚动连接性能更优,同样可以实现精确时间匹配的滞后需求:
library(data.table) library(lubridate) # 构造测试data.table dt <- data.table( ts = ymd_hms("2023-04-12T00:00:00") + hours(seq(1,48,8)), v = 1:6 ) # 创建偏移后的时间列,通过左连接匹配对应值(仅精确匹配) dt[, ts_lag := ts - days(1)] dt[dt, on = .(ts = ts_lag), v_lag := i.v, roll = FALSE] # 查看结果 dt
这里roll = FALSE确保只有当偏移后的时间戳精确存在时才返回对应值,否则为NA,符合需求。
内容的提问来源于stack exchange,提问作者mpettis
相关产品推荐
相关产品推荐

