在R中将时间相加

4
日期和时间在R语言中很容易令人困惑。我只想随机生成一些24小时制的时间,然后再将它们相加。
随机生成如下所示:
library(lubridate)

hourTime <- as.list(format(seq.POSIXt(as.POSIXct(Sys.Date()),
                                    as.POSIXct(Sys.Date()+1),
                                    by = "5 min"),
                         "%H:%M", tz="GMT"))

尝试转换为日期:

df$ARRIVALTIME <- replicate(1000, sample(hourTime, 1, replace=F))

尝试在之前的时间上添加:

df$TRETTIME <- df$ARRIVALTIME +
    (hours(sample(1:3, 1000, replace=T)) + minutes(sample(1:60, 1000, replace=T)))

我猜这个失败是因为我没有一个格式化的时间对象。我该如何将随机时间添加到ARRIVALTIME

hours()minutes()是从哪里来的?你自己写的吗?为什么需要在hourTime中使用as.list() - MrFlick
@MrFlick。这些来自lubridate(已更新代码)。as.List是为了我可以从中进行抽样。 - Sebastian Zeki
hourTime 只是一个字符字符串列表,不是吗? - thelatemail
2个回答

8

这个问题很简单——底层的POSIXt可以是长格式/按元素分割的POSIXlt(在此不适用)或者紧凑的POSIXct,它只是一个双精度浮点数(也称为numeric),你可以进行数学计算。

所以,你可以按照自己的方式创建时间,然后添加实际值即可:

R> now <- Sys.time()
R> set.seed(123)
R> deltas <- cumsum(rnorm(5))    # just five N(0,1), added up 
R> 
R> now
[1] "2018-06-14 16:50:36.55687 CDT"
R> 
R> now + deltas
[1] "2018-06-14 16:50:35.996404 CDT" "2018-06-14 16:50:35.766226 CDT"
[3] "2018-06-14 16:50:37.324935 CDT" "2018-06-14 16:50:37.395443 CDT"
[5] "2018-06-14 16:50:37.524731 CDT"
R> 

一旦你理解了基础类型,就几乎没必要使用附加包,因为一切都可以在(分数)秒内完成。所以要加一个小时,只需60*60等等。 附加包仍然有用的是业务日约定、节假日和额外的解析器。
您代码片段中的问题是format()破坏了Datetime对象: 您要求R创建一个字符串,它也确实这样做了。但在此之后,您不能再进行计算。因此,先进行计算,然后再进行漂亮的打印或格式化。

2
不要忘记可靠的 as.difftime - Sys.time() + as.difftime(1, units="days") 如果你想要明确添加单位(天/小时/分钟/秒)。 - thelatemail
当然可以,但是OP要求随机性。 - Dirk Eddelbuettel

3
当您使用format函数时,创建的字符变量无法进行求和。因此,建议将其保留为POSIXt格式,必要时再转换为字符。
另外,lubridate中的minuteshours函数会创建一个period对象,当该对象在列表中时,会被转换为数字,因此无法使用列表进行求和(我不完全理解这部分内容)。无论如何,如果我理解正确,通过以下代码,我已经成功地得到了您想要的结果,而且没有使用列表(如果需要,您可以将结果放在一个列表中):
hourTime<-(seq.POSIXt(as.POSIXct(Sys.Date()),
                         as.POSIXct(Sys.Date()+1),
                         by = "5 min"))


ARRIVALTIME <- sample(hourTime, 1000, replace=T)
TRETTIME <- ARRIVALTIME +
    (hours(sample(1:3, 1000, replace=T)) +
                     minutes(sample(1:60, 1000, replace=T)))

我使用了sample(hourTime, 1000, replace=T)代替replicate(1000, sample(hourTime, 1, replace=F)),我猜这两种方法的作用是相同的。两种方法都可以使用。 - André Costa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接