简体   繁体   English

从起始年月开始连续几个月创建 n 个不同的日期

[英]Create n different dates in consecutive months from a starting year-month

I have a starting time specified as a year-month character, eg "2020-12".我将开始时间指定为year-month字符,例如“2020-12”。 From the start, for each of T consecutive months, I need to generate n different dates (year-month-day), where the day is random.从一开始,对于每个连续的T个月,我需要生成n不同的日期(年-月-日),其中日期是随机的。

Any help will be useful!任何帮助都会很有用!

The data I'm working on:我正在处理的数据:

data <- data.frame(
  data = sample(seq(as.Date('2000/01/01'), as.Date('2020/01/01'), by="day"), 500),
  price = round(runif(500, min = 10, max = 20),2),
  quantity = round(rnorm(500,30),0)
)
func <- function(start, months, n) {
  startdate <- as.Date(paste0(start, "-01"))
  enddate <- seq(startdate, by = "month", length.out = months)
  months <- seq_len(months)
  enddate_lt <- as.POSIXlt(enddate)
  enddate_lt$mon <- enddate_lt$mon + 1
  enddate_lt$mday <- enddate_lt$mday - 1
  days_per_month <- as.integer(format(enddate_lt, format = "%d"))
  days <- lapply(days_per_month, sample, size = n)
  dates <- Map(`+`, enddate, days)
  do.call(c, dates)
}

set.seed(2021)
func("2020-12", 4, 3)
#  [1] "2020-12-08" "2020-12-07" "2020-12-15" "2021-01-27" "2021-01-08" "2021-01-13" "2021-02-21" "2021-02-07" "2021-02-28"
# [10] "2021-03-28" "2021-03-07" "2021-03-15"
func("2020-12", 5, 2)
#  [1] "2020-12-06" "2020-12-16" "2021-01-08" "2021-01-10" "2021-02-24" "2021-02-13" "2021-03-20" "2021-03-29" "2021-04-19"
# [10] "2021-04-28"
func("2020-12", 2, 10)
#  [1] "2020-12-29" "2020-12-30" "2020-12-04" "2020-12-15" "2020-12-09" "2020-12-27" "2020-12-05" "2020-12-06" "2020-12-23"
# [10] "2020-12-17" "2021-01-03" "2021-01-20" "2021-01-05" "2021-01-22" "2021-01-23" "2021-01-06" "2021-01-10" "2021-01-07"
# [19] "2021-01-19" "2021-01-12"

Most of the dancing with POSIXlt objects is because it gives us clean (base R) access to the number of days in a month, which makes sample ing the days in a month rather simple.POSIXlt对象共舞的大部分原因是因为它使我们能够干净地(以 R 为基础)访问一个月中的天数,这使得对一个月中的天数进行sample变得相当简单。 It can also be done (code-golf shorter) using the lubridate package, but I don't know that that is any more correct than this code is.也可以使用lubridate package 来完成(代码高尔夫更短),但我不知道这比这段代码更正确。

This just dumps out a sequence of random dates, with n days per month.这只是转储了一系列随机日期,每个月有n天。 It does not sort within each month, though it does output the months in order.它不会在每个月内进行排序,尽管它会按月份顺序执行 output。 (That's not a difficult extension, there just wasn't a requirement for it.) It doesn't put out a frame, you can easily extend this to fit in a frame or call data.frame(date = do.call(c, dates)) on the last line, depending on what you need to do with the output. (这不是一个困难的扩展,只是没有要求。)它不输出框架,您可以轻松扩展它以适应框架或调用data.frame(date = do.call(c, dates))在最后一行,具体取决于您需要对 output 做什么。

You could convert the start time to a class for monthly data, zoo::yearmon .您可以将开始时间转换为 class 以获取每月数据zoo::yearmon Then use as.Date.yearmon and its frac argument ("a number between 0 and 1 inclusive that indicates the fraction of the way through the period that the result represents") with random values from runif (uniform between 0 and 1) to convert to a random date within each year-month.然后使用as.Date.yearmon及其frac参数(“一个介于 0 和 1 之间的数字,表示结果所代表的时间段的分数”)与来自runif的随机值(0 和 1 之间的统一)进行转换到每个年月内的随机日期。

start = "2020-12"
T = 3
n = 2

library(zoo)
set.seed(1)
as.Date(as.yearmon(start) + rep((1:T)/12, each = n), frac = runif(T * n))
# [1] "2021-01-08" "2021-01-12" "2021-02-16" "2021-02-25" "2021-03-07" "2021-03-27"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM