从日期向量中选择和分组相似日期
Selecting and grouping similar dates from vectors of dates
我有三个 POSIX 格式的日期向量,它们与来自三个大型数据集的数据收集时间相对应。这些向量中的每一个都具有不同的长度并且具有相似(但不相同)的日期。
我愿意:
- 将这些日期分组到指定的时间范围内,例如将属于 30 天 window 和
的每个矢量的日期分组
- 减少日期分组的数量以反映收集次数最少的数据集,例如如果“数据集 A”有三个采样日期而“数据集 B”有五个采样日期,则只有三组日期(除非“数据集 B”中的两个额外日期落在“数据集 A”中的日期的 30 天内).
包含三个日期向量的示例 POSIX 格式(我想将向量之间的相似日期分组,允许 30 天的时间 window):
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")
指定时间 window 为 30 天,将有三个日期分组(采样日期为 1998 年 7 月、1999 年和 2000 年)。 C.dates
载体的第四个收集日期为 2000 年 8 月 29 日,该日期将被排除在分组之外,因为:
- 它不在其他向量中 7 月日期的 30 天内并且
- 其他两个向量中没有落在 2000 年 8 月 29 日之后 30 天内的日期。
您可以遍历每个向量的每个元素并创建 seq
uences ± 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"))))
和union
将它们添加到列表中。
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)
和 select 相应的日期。
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
列出了前四个 substr
年份(不过我们也可以 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"
我有三个 POSIX 格式的日期向量,它们与来自三个大型数据集的数据收集时间相对应。这些向量中的每一个都具有不同的长度并且具有相似(但不相同)的日期。
我愿意:
- 将这些日期分组到指定的时间范围内,例如将属于 30 天 window 和 的每个矢量的日期分组
- 减少日期分组的数量以反映收集次数最少的数据集,例如如果“数据集 A”有三个采样日期而“数据集 B”有五个采样日期,则只有三组日期(除非“数据集 B”中的两个额外日期落在“数据集 A”中的日期的 30 天内).
包含三个日期向量的示例 POSIX 格式(我想将向量之间的相似日期分组,允许 30 天的时间 window):
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")
指定时间 window 为 30 天,将有三个日期分组(采样日期为 1998 年 7 月、1999 年和 2000 年)。 C.dates
载体的第四个收集日期为 2000 年 8 月 29 日,该日期将被排除在分组之外,因为:
- 它不在其他向量中 7 月日期的 30 天内并且
- 其他两个向量中没有落在 2000 年 8 月 29 日之后 30 天内的日期。
您可以遍历每个向量的每个元素并创建 seq
uences ± 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"))))
和union
将它们添加到列表中。
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)
和 select 相应的日期。
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
列出了前四个 substr
年份(不过我们也可以 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"