给定月份中每天的一年中的一天

时间:2019-11-06 10:10:49

标签: r lubridate

我想在R中有一个函数month2doty(),如果提供了代表月份的数字(例如,2代表2月),则返回一个包含一年中天的向量表示该月的每一天(因此32, 33, 34, …, 59表示2月):

> month2doty(2)
 [1] 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

飞跃岁月在我的世界中不存在。我在下面提供了一个可能的答案,但是我确定有更好的解决方案?

2 个答案:

答案 0 :(得分:1)

这是在基数R中执行此操作的另一种方法。我们在月初和下个月之间创建2个长度的序列,然后生成它们之间的所有日期。我们使用%j中的format来显示这些日期的年份。

month2doty <- function(x) {

  days <- seq(as.Date(paste0(format(Sys.Date(), "%Y"), "-", x, "-01")), 
                       by = "1 month", length.out = 2)
  as.integer(format(seq(days[1], days[2] - 1, by = "day"), "%j"))
}

month2doty(2)
# [1] 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 
#     54 55 56 57 58 59

month2doty(12)
# [1] 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 
#     354 355 356 357 358 359 360 361 362 363 364 365

或者仅使用一次seq并使用days_in_month中的lubridate的另一种版本

library(lubridate)

month2doty <- function(x) {
   days <- as.Date(paste0(format(Sys.Date(), "%Y"), "-", x, "-01")) 
   as.integer(format(seq(days, days + days_in_month(x) - 1, by = "day"), "%j"))
}

如果我们不想以不同的方式对待leap年,则可以对年份进行硬编码(如在OP中一样)

month2doty <- function(x) {
  days <- seq(as.Date(paste0("2015-", x, "-01")), by = "1 month", length.out = 2)
  as.integer(format(seq(days[1], days[2] - 1, by = "day"), "%j"))
}

month2doty <- function(x) {
   days <- as.Date(paste0("2015-", x, "-01")) 
   as.integer(format(seq(days, days + days_in_month(x) - 1, by = "day"), "%j"))
}

答案 1 :(得分:0)

我当前的解决方案是,每次调用该函数时,查找表的构造都有些笨拙:

month2doty <- function(mon=1){
  require(lubridate)
  alldays <- seq(from=ymd("2015-01-01"), length.out=365, by="days")
  lookuptable <- data.frame(month=month(alldays), day=day(alldays), doty=yday(alldays) )
  monthdata <- subset(lookuptable, lookuptable$month==mon)
  return(monthdata$doty)
}

month2doty(2)

它可以像这样正常工作,但是我想知道这里是否缺少更干净的解决方案。