【问题标题】:Is there an inverse of the yday lubridate function?是否存在 yday lubridate 函数的逆函数?
【发布时间】:2017-04-23 04:36:27
【问题描述】:

通过将 lubridate::yday() 函数应用于日期列表,我有一个格式为“一年中的某天”的日期列表。例如,从以下日期开始(mm-dd-yyyy 格式):

01-01-2015
01-02-2015
...

通过应用 yday() 你得到

1
2
...

在给定 yday 输出和年份的情况下,是否有可以反向执行的函数?即,从 yday 值和年份,返回 mm-dd-yyyy 格式的日期?

【问题讨论】:

  • 我相信这类问题在 StackOverflow 上会更好。
  • 一种解决方案可能只是创建一个天序列(mm-dd-yyyy 格式),对天应用 lubridate::yday() 函数并获取年份。然后只需做一个简单的合并或加入。不要想太多。
  • 您确实不需要需要合并。 R有日期算术。看我的回答。

标签: r date-arithmetic


【解决方案1】:

要使用 lubridate 包执行此操作,您可以使用 parse_date_time() 函数和 j 作为 order = 参数。

例子:

my.yday <- "1"
parse_date_time(x = my.yday, orders = "j") 
# [1] "2021-01-01 UTC"

默认值似乎是当前年份。如果你想指定年份,只需添加它!

my.yday <- "1"
parse_date_time(x = paste(1995, my.yday), orders = "yj")
# [1] "1995-01-01 UTC"

注意:确保您提供的儒略日是字符,而不是数字。如果是数字,当超过 3 位时它会失败(他们不打算修复的奇怪错误)

【讨论】:

  • 注意:目前包中有一个bug,如果yday >= 100,它只解析字符格式。在他们解决此问题之前,您的代码中的解决方法是提供 yday 作为字符向量而不是数字向量。
【解决方案2】:

正如@DirkEddelbuettel 的回答一样,因为我遇到了同样的问题并且已经 3 年了。

为了获得给定数据集所需的 mm-dd-yyyy,在 lubridate::yday() 的结果中您只有年份和日历日。

您只需要从 1 月 1 日开始为给定年份偏移一个 Date() 类型对象,即您的 yday() 输出减去 1。

然后,如果您想获取该月内的月份或日期,您可以使用 lubridate 的 month()day() 函数来提取这些部分。

(我假设您有年份,因为那会影响闰年的日历日期 b/c,弄乱您的月/日分配。如果没有,任何年份都可以)

library(dplyr)
library(magrittr)

#Example dataset with years on/around leap year
my_df <- data.frame(
  year = c(2010, 2011, 2012, 2013, 2014, 2015),
  my_yday = c(150, 150, 150, 150, 150, 150)
)


#skip straight back to the yyyy-mm-dd format
my_df %>% mutate(new_date = as.Date(paste0(year, "-01-01")) + (my_yday - 1))

#Get every component
my_df %>%
  mutate(
    new_day   = lubridate::day(as.Date(str_c(year, "-01-01")) + (my_yday - 1)),
    new_month = lubridate::month(as.Date(paste0(year, "-01-01")) + (my_yday - 1)),
    new_date  = as.POSIXct(str_c(new_month, new_day, year, sep = "/"), 
                           format = "%m/%d/%y"))



【讨论】:

    【解决方案3】:

    任何添加到 Date() 类型的序列 都会创建一个新的 Date() 序列,其中只有该偏移量。

    证人:

    R> as.Date("2016-01-01") + 0:9
     [1] "2016-01-01" "2016-01-02" "2016-01-03"
     [4] "2016-01-04" "2016-01-05" "2016-01-06"
     [7] "2016-01-07" "2016-01-08" "2016-01-09"
    [10] "2016-01-10"
    R> as.Date("2016-01-01") + 100:109
     [1] "2016-04-10" "2016-04-11" "2016-04-12"
     [4] "2016-04-13" "2016-04-14" "2016-04-15"
     [7] "2016-04-16" "2016-04-17" "2016-04-18"
    [10] "2016-04-19"
    R> 
    

    所以又是一个所谓的 lubridate 问题,与该包无关,只需要知道基本 R 类型的功能。

    【讨论】:

    • 很好 - 总是喜欢简单的约会解决方案。此外,as.Date(paste(100,2015), format="%j %Y") 将正常工作。
    • 有趣。没试过'yearday year';说得通。在“weeknum year”失败之前就注意到了——这不是七种可能性中未定的日期。 'weekday weeknum year' 有效。但是重新解析不如添加:)
    • 感谢匿名 SO 用户的不加评论。总是很高兴看到建设性的批评进一步改进已经有效的答案。哦,等等,...
    • 坚持使用OP已经熟悉的lubridate语法可能更简单,并使用parse_date_time(..., orders = "j")
    【解决方案4】:
    > yday ("1990-03-17") - 1 + as.Date ("1990-01-01")
    [1] "1990-03-17"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多