【问题标题】:Selecting and grouping similar dates from vectors of dates从日期向量中选择和分组相似的日期
【发布时间】:2021-03-28 20:46:42
【问题描述】:

我有三个 POSIX 格式的日期向量,它们与来自三个大型数据集的数据收集时间相对应。这些向量中的每一个都具有不同的长度并且具有相似(但不相同)的日期。

我想:

  1. 将这些日期分组到指定的时间范围内,例如每个向量的分组日期在 30 天的窗口内,并且
  2. 减少日期分组的数量以反映收集次数最少的数据集,例如如果“数据集 A”有三个采样日期,“数据集 B”有五个采样日期,则只有三组日期(除非“数据集 B”中的两个额外日期在“数据集 A”中的日期的 30 天内)。

以 POSIX 格式包含三个日期向量的示例(我想在向量之间对相似的日期进行分组,允许 30 天的时间窗口):

A.dates = as.POSIXlt(c("1998-07-24 08:00","1999-07-24 08:00","2000-07-24 08:00"), 
                     tz = "America/Los_Angeles")
B.dates = as.POSIXlt(c("1998-07-25 08:00","1999-07-25 08:00","2000-07-25 08:00"), 
                     tz = "America/Los_Angeles")
C.dates = as.POSIXlt(c("1998-07-26 08:00","1999-07-26 08:00","2000-07-26 08:00","2000-08-29"), 
                     tz = "America/Los_Angeles") 

指定 30 天的时间窗口,将有三个日期分组(抽样日期为 1998 年 7 月、1999 年和 2000 年)。 C.dates 向量的第四个收集日期为 2000 年 8 月 29 日,该日期将被排除在分组之外,因为:

  1. 不在其他向量中的 7 月日期的 30 天内,并且
  2. 其他两个向量中没有日期在 2000 年 8 月 29 日后 30 天内。

【问题讨论】:

    标签: r date time-series grouping posixlt


    【解决方案1】:

    您可以遍历每个向量的每个元素并创建 sequences ± 15 天

    L <- list(A.dates, B.dates, C.dates)
    tmp <- lapply(L, function(x) lapply(x, function(x) 
      do.call(seq, c(as.list(as.Date(x) + c(-15, 15)), "day"))))
    

    unionite 他们在列表中。

    tmp <- lapply(tmp, function(x) as.Date(Reduce(union, x), origin="1970-01-01"))
    

    然后只需找到intersect

    i <- Reduce(function(...) as.Date(intersect(...), origin="1970-01-01"), tmp)
    

    并相应地选择日期。

    tmp <- lapply(L, function(x) x[as.Date(x) %in% i])
    tmp
    # [[1]]
    # [1] "1998-07-24 08:00:00 PDT" "1999-07-24 08:00:00 PDT"
    # [3] "2000-07-24 08:00:00 PDT"
    # 
    # [[2]]
    # [1] "1998-07-25 08:00:00 PDT" "1999-07-25 08:00:00 PDT"
    # [3] "2000-07-25 08:00:00 PDT"
    # 
    # [[3]]
    # [1] "1998-07-26 PDT" "1999-07-26 PDT" "2000-07-26 PDT"
    

    要根据您的评论按年份对它们进行排序,我们首先unlist它们。不幸的是,这会将日期转换为数字(即自 1970 年 1 月 1 日以来的秒数),因此我们需要将它们转换回来。

    tmp <- as.POSIXlt(unlist(lapply(tmp, as.POSIXct)), origin="1970-01-01",
                    tz="America/Los_Angeles")
    

    最后我们split 列出了前四个substrings 的列表(不过我们也可以使用split(tmp, strftime(tmp, "%Y")))。

    res <- split(tmp, substr(tmp, 1, 4))
    res
    # $`1998`
    # [1] "1998-07-24 08:00:00 PDT" "1998-07-25 08:00:00 PDT"
    # [3] "1998-07-26 00:00:00 PDT"
    # 
    # $`1999`
    # [1] "1999-07-24 08:00:00 PDT" "1999-07-25 08:00:00 PDT"
    # [3] "1999-07-26 00:00:00 PDT"
    # 
    # $`2000`
    # [1] "2000-07-24 08:00:00 PDT" "2000-07-25 08:00:00 PDT"
    # [3] "2000-07-26 00:00:00 PDT"
    

    【讨论】:

    • 如何将最终输出放入日期分组列表中,即 1998 年的日期将是一个列表,1999 年的日期将是下一个列表,等等?谢谢!到目前为止一切都很完美
    • @eabrown2378 请参阅编辑。请注意,我将一些只需要一次的对象重命名为 tmp,以免使工作区过于混乱。
    • 有没有办法按照 ± 15 天的标准而不是年份对它们进行分组。考虑我们在一年中有多个采样日期但不在 15 天内的情况,即我们需要两个 1998 年的列表
    • @eabrown2378 我明白,但这很棘手,因为 ±15 列表中的向量确实重叠。
    • @eabrown2378 无论如何,代码类似于lapply(criteria15, function(x) tmp[as.Date(tmp) %in% x])(最后一个tmp)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2020-02-05
    • 2014-04-22
    • 1970-01-01
    • 2020-07-10
    相关资源
    最近更新 更多