返回最小时间步长
我正在用R 构建一个自动化工作流。因此,我处理的是与时间相关的数据。为了进行聚合,我想要一种让R 告诉我日期所具有的最小时间步长,并且要符合lubridate包的时间单位(例如 "year"、"month"、"week" 等)。
所以当我有这样的数据时:
dates_m <- c("2021-05-01", "2021-06-01", "2021-07-01")
dates_d <- c("2021-05-01", "2021-05-02", "2021-05-14")
我希望输出看起来像这样:
cool_function(dates_m)
> "month"
cool_function(dates_d)
> "day"
我甚至没有一个我尝试过的例子,因为我还没有找到应对这个问题的方法。我在lubridate包中没有发现能够实现这个的函数,而我的做法包含大量的if条件。太多了,以至于我相信一定有更聪明的实现方式。
编辑:
我应该说明,应该输入到这个函数中的日期,之前是由 lubridate::round_date() 或其相关函数族 floor_date() 和 ceiling_date() 生成的。我不知道这是否有帮助,但我认为应该提供这些信息。关键在于,这个函数应能找出这些函数之一使用的时间单位。
解决方案
尝试检查 time_length 是否能得到单位的合适倍数。
使用 filter = min 时,它只检查最小区间,正如要求;或使用 filter = identity 时,它会检查所有区间。用示例数据时,filter 的两个值给出相同的结果,但不同输入时它们也可能不同。
check_impl <- function(x, unit, divisor, filter) {
interval(lag(x), x) %>%
time_length(unit = unit) %>%
tail(-1) %>% # rm NA at beginning
filter %>%
{ all(. %% divisor == 0) }
}
check_units <- function(x, filter = min) {
case_when(
check_impl(x, "month", 12, filter) ~ "year",
check_impl(x, "month", 6, filter) ~ "halfyear",
check_impl(x, "month", 3, filter) ~ "quarter",
check_impl(x, "month", 2, filter) ~ "bimonthly",
check_impl(x, "month", 1, filter) ~ "month",
check_impl(x, "day", 7, filter) ~ "week",
TRUE ~ "day"
)
}
现在来测试一下:
check_units(dates_m) # "month"
check_units(dates_w) # "week"
check_units(dates_d) # "week"
check_units(dates_m, identity) # "month"
check_units(dates_w, identity) # "week"
check_units(dates_d, identity) # "day"
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。