将日期转换为数字但限制为一年中的天数
Converting date to numeric but limiting to number of days in year
我想在 2008-01-01 和 2010-12-31 之间创建大约 10K 个日期对象。我为此编写了代码,但实际上我想在 2008 年保留 1-366 天,因为 2008-02-29(闰年)我希望它们在 366 之后重新启动,然后在 2009-01-01 变为 1。我可以只为 2008 年然后 2009 年然后 2010 年创建,但这并不方便。我正在阅读有关 lubridate
的内容,但无法弄清楚。我也可以过滤 1 到 366,然后过滤 367-731,但这也不会有效。有人知道更好的方法吗?
set.seed(123)
tim1=sample(365*3+1,10000,replace = TRUE) ### that plus 1 from feb 29 in 2008
dat1=as.Date(tim1,origin="2007-12-31") # then 1 will be 2008-01-01
您可以创建一个包含所有目标日期的向量并从中抽样。要创建矢量,有 seq.Date
,seq
对象的方法 class "Date"
。
start <- as.Date("2008-01-01")
end <- as.Date("2010-12-31")
s <- seq(start, end, by = "days")
矢量 s
包括 start
和 end
之间的所有日期。现在从中取样。
set.seed(123)
dat1 <- sample(s, 10000, TRUE)
将示例转换为一年中的某一天。参见 help("strptime")
as.numeric(format(dat1, format = "%j"))
最后,删除s
,不再需要了。
rm(s) # tidy up
编辑。
以下两个函数执行问题要求的操作,但使用两种不同的方法。
f1
是上面包裹在函数中的代码,f2
使用 ave/seq_along/match
并且有点复杂。测试显示函数 f2
比 f1
快两倍
f1 <- function(start_date, end_date, n){
start <- as.Date(start_date)
end <- as.Date(end_date)
s <- seq(start, end, by = "days")
y <- sample(s, n, replace = TRUE)
as.numeric(format(y, format = "%j"))
}
f2 <- function(start_date, end_date, n){
start <- as.Date(start_date)
end <- as.Date(end_date)
s <- seq(start, end, by = "days")
y <- sample(s, n, replace = TRUE)
z <- ave(as.integer(s), lubridate::year(s), FUN = seq_along)
z[match(y, s)]
}
set.seed(123)
x1 <- f1("2008-01-01", "2010-12-31", 100)
set.seed(123)
x2 <- f2("2008-01-01", "2010-12-31", 100)
all.equal(x1, x2)
#[1] TRUE
现在开始测试。
library(microbenchmark)
mb <- microbenchmark(
f1 = f1("2008-01-01", "2010-12-31", 1e4),
f2 = f2("2008-01-01", "2010-12-31", 1e4),
times = 50
)
print(mb, order = "median")
ggplot2::autoplot(mb)
我想在 2008-01-01 和 2010-12-31 之间创建大约 10K 个日期对象。我为此编写了代码,但实际上我想在 2008 年保留 1-366 天,因为 2008-02-29(闰年)我希望它们在 366 之后重新启动,然后在 2009-01-01 变为 1。我可以只为 2008 年然后 2009 年然后 2010 年创建,但这并不方便。我正在阅读有关 lubridate
的内容,但无法弄清楚。我也可以过滤 1 到 366,然后过滤 367-731,但这也不会有效。有人知道更好的方法吗?
set.seed(123)
tim1=sample(365*3+1,10000,replace = TRUE) ### that plus 1 from feb 29 in 2008
dat1=as.Date(tim1,origin="2007-12-31") # then 1 will be 2008-01-01
您可以创建一个包含所有目标日期的向量并从中抽样。要创建矢量,有 seq.Date
,seq
对象的方法 class "Date"
。
start <- as.Date("2008-01-01")
end <- as.Date("2010-12-31")
s <- seq(start, end, by = "days")
矢量 s
包括 start
和 end
之间的所有日期。现在从中取样。
set.seed(123)
dat1 <- sample(s, 10000, TRUE)
将示例转换为一年中的某一天。参见 help("strptime")
as.numeric(format(dat1, format = "%j"))
最后,删除s
,不再需要了。
rm(s) # tidy up
编辑。
以下两个函数执行问题要求的操作,但使用两种不同的方法。
f1
是上面包裹在函数中的代码,f2
使用 ave/seq_along/match
并且有点复杂。测试显示函数 f2
比 f1
f1 <- function(start_date, end_date, n){
start <- as.Date(start_date)
end <- as.Date(end_date)
s <- seq(start, end, by = "days")
y <- sample(s, n, replace = TRUE)
as.numeric(format(y, format = "%j"))
}
f2 <- function(start_date, end_date, n){
start <- as.Date(start_date)
end <- as.Date(end_date)
s <- seq(start, end, by = "days")
y <- sample(s, n, replace = TRUE)
z <- ave(as.integer(s), lubridate::year(s), FUN = seq_along)
z[match(y, s)]
}
set.seed(123)
x1 <- f1("2008-01-01", "2010-12-31", 100)
set.seed(123)
x2 <- f2("2008-01-01", "2010-12-31", 100)
all.equal(x1, x2)
#[1] TRUE
现在开始测试。
library(microbenchmark)
mb <- microbenchmark(
f1 = f1("2008-01-01", "2010-12-31", 1e4),
f2 = f2("2008-01-01", "2010-12-31", 1e4),
times = 50
)
print(mb, order = "median")
ggplot2::autoplot(mb)