在 R 中修改日期
Munging dates in R
我正在处理一个数据处理管道,其中包含大量数据中的日期列。许多 R 函数(例如,集合运算、sapply
等)不保留日期 class,将日期转换为整数。
我认为处理此问题的策略是:
- 确保数据处理管道中的每个函数都接受 returns 格式化为日期的日期。缺点:弄清楚所有要粘贴的地方
as.Date()
通常很乏味。
- 在所有处理步骤中将日期作为整数生活,仅在最后将它们转换为日期。这样做的缺点是,如果不首先转换为日期,就不可能在中间修改步骤中进行日期操作(例如,使用
by = "month"
排序)。
我还缺少其他选项吗?有没有办法让 R 与日期一起玩?澄清一下,我正在处理的数据不仅仅是一个时间序列:多个列包含日期。因此,据我所知,xts
的用处有限。
将对 sapply
的调用替换为执行您想要的操作的函数可能并不难。例如,
sapply2 <- function(X, FUN, ...) {
do.call(c, lapply(X, FUN, ...))
}
这不像原来的 sapply
那样通用,但如果您在 sapply(X, FUN)
returns 日期使用的函数,它将保留它们。如果你想使用 sapply
的可选参数,你需要更详细的东西。
我不知道您的 "etc." 中还有多少其他功能,但我猜不会很多,而且大多数修复都不是那么难。
不保留 Date
class 错误特征是 R 本身的人工产物,以及一些基本 R 函数的实现方式。请参阅 例如
R> dates <- Sys.Date() + 0:2
R> for (d in dates) cat(d, "\n")
17532
17533
17534
R>
本质上,S3 class 属性在您执行某些向量操作时会被删除:
R> as.vector(dates)
[1] 17532 17533 17534
R>
所以我的建议是选择一个你喜欢的好的容器类型并坚持在那里进行操作。为此,我非常喜欢 data.table 。一个简单的例子:
R> suppressMessages(library(data.table))
R> dt <- data.table(date=Sys.Date()+0:2, other=Sys.Date() + cumsum(runif(3)*100))
R> dt[, diff:=other-date][]
date other diff
1: 2018-01-01 2018-03-30 88.88445 days
2: 2018-01-02 2018-06-09 158.23913 days
3: 2018-01-03 2018-07-30 208.62187 days
R> dt[, month:=month(other)][]
date other diff month
1: 2018-01-01 2018-03-30 88.88445 days 3
2: 2018-01-02 2018-06-09 158.23913 days 6
3: 2018-01-03 2018-07-30 208.62187 days 7
R>
不仅 Date
类型持久化(差异操作返回 difftime
对象证明),而且您还获得了很多帮助器
函数(如 month()
)在这里。按日期分组也很自然。
我正在处理一个数据处理管道,其中包含大量数据中的日期列。许多 R 函数(例如,集合运算、sapply
等)不保留日期 class,将日期转换为整数。
我认为处理此问题的策略是:
- 确保数据处理管道中的每个函数都接受 returns 格式化为日期的日期。缺点:弄清楚所有要粘贴的地方
as.Date()
通常很乏味。 - 在所有处理步骤中将日期作为整数生活,仅在最后将它们转换为日期。这样做的缺点是,如果不首先转换为日期,就不可能在中间修改步骤中进行日期操作(例如,使用
by = "month"
排序)。
我还缺少其他选项吗?有没有办法让 R 与日期一起玩?澄清一下,我正在处理的数据不仅仅是一个时间序列:多个列包含日期。因此,据我所知,xts
的用处有限。
将对 sapply
的调用替换为执行您想要的操作的函数可能并不难。例如,
sapply2 <- function(X, FUN, ...) {
do.call(c, lapply(X, FUN, ...))
}
这不像原来的 sapply
那样通用,但如果您在 sapply(X, FUN)
returns 日期使用的函数,它将保留它们。如果你想使用 sapply
的可选参数,你需要更详细的东西。
我不知道您的 "etc." 中还有多少其他功能,但我猜不会很多,而且大多数修复都不是那么难。
不保留 Date
class 错误特征是 R 本身的人工产物,以及一些基本 R 函数的实现方式。请参阅 例如
R> dates <- Sys.Date() + 0:2
R> for (d in dates) cat(d, "\n")
17532
17533
17534
R>
本质上,S3 class 属性在您执行某些向量操作时会被删除:
R> as.vector(dates)
[1] 17532 17533 17534
R>
所以我的建议是选择一个你喜欢的好的容器类型并坚持在那里进行操作。为此,我非常喜欢 data.table 。一个简单的例子:
R> suppressMessages(library(data.table))
R> dt <- data.table(date=Sys.Date()+0:2, other=Sys.Date() + cumsum(runif(3)*100))
R> dt[, diff:=other-date][]
date other diff
1: 2018-01-01 2018-03-30 88.88445 days
2: 2018-01-02 2018-06-09 158.23913 days
3: 2018-01-03 2018-07-30 208.62187 days
R> dt[, month:=month(other)][]
date other diff month
1: 2018-01-01 2018-03-30 88.88445 days 3
2: 2018-01-02 2018-06-09 158.23913 days 6
3: 2018-01-03 2018-07-30 208.62187 days 7
R>
不仅 Date
类型持久化(差异操作返回 difftime
对象证明),而且您还获得了很多帮助器
函数(如 month()
)在这里。按日期分组也很自然。