有效地生成两个日期之间的时间和日期的随机样本

the*_*ail 33 random datetime r date

我写了一个(相当幼稚的)函数来随机选择两个指定日期之间的日期/时间

# set start and end dates to sample between
day.start <- "2012/01/01"
day.end <- "2012/12/31"

# define a random date/time selection function
rand.day.time <- function(day.start,day.end,size) {
  dayseq <- seq.Date(as.Date(day.start),as.Date(day.end),by="day")
  dayselect <- sample(dayseq,size,replace=TRUE)
  hourselect <- sample(1:24,size,replace=TRUE)
  minselect <- sample(0:59,size,replace=TRUE)
  as.POSIXlt(paste(dayselect, hourselect,":",minselect,sep="") )
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

> rand.day.time(day.start,day.end,size=3)
[1] "2012-02-07 21:42:00" "2012-09-02 07:27:00" "2012-06-15 01:13:00"
Run Code Online (Sandbox Code Playgroud)

但随着样本量的增加,这似乎在大幅放缓.

# some benchmarking
> system.time(rand.day.time(day.start,day.end,size=100000))
   user  system elapsed 
   4.68    0.03    4.70 
> system.time(rand.day.time(day.start,day.end,size=200000))
   user  system elapsed 
   9.42    0.06    9.49 
Run Code Online (Sandbox Code Playgroud)

有人能够以更有效的方式建议如何做这样的事情吗?

Dir*_*tel 45

啊,另一个日期/时间问题,我们可以减少到浮动工作:)

试试这个功能

R> latemail <- function(N, st="2012/01/01", et="2012/12/31") {
+     st <- as.POSIXct(as.Date(st))
+     et <- as.POSIXct(as.Date(et))
+     dt <- as.numeric(difftime(et,st,unit="sec"))
+     ev <- sort(runif(N, 0, dt))
+     rt <- st + ev
+ }
R>
Run Code Online (Sandbox Code Playgroud)

我们difftime以秒为单位计算,然后"仅仅"在其上绘制制服,对结果进行排序.将它添加到开头,您就完成了:

R> set.seed(42); print(latemail(5))     ## round to date, or hour, or ...
[1] "2012-04-14 05:34:56.369022 CDT" "2012-08-22 00:41:26.683809 CDT" 
[3] "2012-10-29 21:43:16.335659 CDT" "2012-11-29 15:42:03.387701 CST"
[5] "2012-12-07 18:46:50.233761 CST"
R> system.time(latemail(100000))
   user  system elapsed 
  0.024   0.000   0.021 
R> system.time(latemail(200000))
   user  system elapsed 
  0.044   0.000   0.045 
R> system.time(latemail(10000000))   ## a few more than in your example :)
   user  system elapsed 
  3.240   0.172   3.428 
R> 
Run Code Online (Sandbox Code Playgroud)

  • 使用日期和时间的第一条规则:*总是*记住`POSIXct`实际上只是一个数字,自theepoch以来的小数秒.Dito为"日期"和分数天.许多问题变得更加容易*. (10认同)
  • 这个答案的天才是"st + ev"技巧 - 它是一个令人痛苦的"POSIXct"的往返,因为你需要明确指定原点.否则`runif(N,as.POSIXct(st),as.POSIXct(et))`获得90%的这个; 但是你需要`as.POSIXct(...,origin ="1970-01-01")` (4认同)