我需要计算“相隔多少 x
个单位” POSIX 日期向量中的每个元素来自给定的引用日期,其中
-
x
是“典型”时间单位,例如月、周、季度等。 - 日期向量可以跨越多年
- 结果必须是
numeric
矢量
我有一些东西,但感觉不是一个可以推广的一致方法(月和周有两种不同的方法)。
可能毫无值(value):我通常寻找符合 ISO 8601 的解决方案
编辑
“一致”是指我理想中的解决方案始终利用 as.numeric(dates)
之后进行一些巧妙的“时间单位分级”。但对于月来说,我不知道如何实现这一目标,因为每个月包含不同的天数(适用于数周,因为我们总是可以安全地说“一周包含 7 天”)。
换句话说:几个月我想使用类似 (as.numeric(.x) / (<something>))
的东西就像我使用(as.numeric(.x) / (60 * 60 * 24 * 7))
一样持续几周。就是那个<something>
我正在寻找一种对日期差异进行分类的通用方法。
解决方案草案
函数定义:
library(magrittr)
library(purrr)
normalize_time_distance_month <- function(dates) {
dates %>%
as.POSIXct() %>%
purrr::map_dbl(function(.x)
as.numeric(format(.x, "%y")) * 12 + as.numeric(format(.x, "%m")))
}
normalize_time_distance_week <- function(dates) {
dates %>%
as.POSIXct() %>%
purrr::map_dbl(function(.x)
(as.numeric(.x) / (60 * 60 * 24 * 7)) %>%
round())
}
月份:
# Months ------------------------------------------------------------------
dates <- seq(as.POSIXct("2018-03-01"), length.out = 24, by = "month")
origin <- as.POSIXct("2018-05-01")
dates_norm <- normalize_time_distance_month(dates)
origin_norm <- normalize_time_distance_month(origin)
(time_diffs <- dates_norm - origin_norm)
#> [1] -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#> [24] 21
周:
# Weeks -------------------------------------------------------------------
dates <- seq(as.POSIXct("2018-05-07"), length.out = 104, by = "week")
origin <- as.POSIXct("2018-05-21")
dates_norm <- normalize_time_distance_week(dates)
origin_norm <- normalize_time_distance_week(origin)
(time_diffs <- dates_norm - origin_norm)
#> [1] -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
#> [18] 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
#> [35] 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#> [52] 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#> [69] 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
#> [86] 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#> [103] 100 101
由reprex package于2018年5月25日创建(v0.2.0)。
最佳答案
一种选择是将表达式作为参数传递,然后解析它
library(tidyverse)
library(rlang)
normalize_time_distance <- function(dates, expr) {
dates %>%
as_tibble %>%
mutate(value = as.POSIXct(value)) %>%
mutate(value = !! parse_expr(expr)) %>%
pull(value)
}
expr1 <- 'as.numeric(format(value, "%y")) * 12 + as.numeric(format(value, "%m"))'
normalize_time_distance(dates, expr1)
#[1] 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
#[20] 238 239 240 241 242
expr2 <- 'round((as.numeric(value) / (60 * 60 * 24 * 7)))'
normalize_time_distance(dates, expr2)
#[1] 2513 2517 2522 2526 2530 2535 2539 2544 2548 2552 2557 2561 2565 2570 2574
#[16] 2578 2583 2587 2591 2596 2600 2604 2609 2613
关于r - 将日期中的差异分箱为跨年的时间单位感知数值向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50530464/