【问题标题】:Day of the year for each day in a given month给定月份中每一天的一年中的某一天
【发布时间】:2019-11-06 10:10:49
【问题描述】:

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

> 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

我的世界不存在闰年。我在下面提供了一个可能的答案,但我确定还有更好的解决方案吗?

【问题讨论】:

    标签: r lubridate


    【解决方案1】:

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

    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 和来自lubridatedays_in_month 的另一个变体

    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"))
    }
    

    如果我们不想区别对待闰年,我们可以硬编码年份(就像在 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"))
    }
    

    【讨论】:

    • 不错,确实优雅多了!
    • 虽然 format(Sys.Date(), "%Y") 如果您在闰年调用该函数会导致二月有 29 天。好吧,对于大多数人来说,这可能比我的解决方案更好。可以将该部分替换为“2015”以与我的解决方案等效。
    【解决方案2】:

    我目前的解决方案是每次调用该函数时都会构建一个有点尴尬的查找表:

    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)
    

    这样工作得很好,但我想知道我在这里是否缺少更清洁的解决方案。

    【讨论】:

      猜你喜欢
      • 2017-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多