【问题标题】:Creating a year/week format for current date in R在 R 中为当前日期创建年/周格式
【发布时间】:2015-02-16 14:07:08
【问题描述】:

我写这篇文章是因为我找不到其他已回答问题的线程。

在 R 中创建“y/w”格式(y 是 2 位数的年份,w 是 2 位数的周数)的最佳代码是什么?
到目前为止,这是我正在使用的:

require(lubridate)
paste(substr(year(Sys.Date()),3,4),sprintf("%02d", isoweek(Sys.Date())), sep="/")

当然,这可能会在一年的最后几天或第一天失败;例如,它可以给出 2016 年 1 月 1 日的“16/53”结果(而应该是“16/01”)。

我正在考虑一些基于 Sys.Date 高于或低于 1 月 1 日的 if-else 构造,并将其与 wday 函数相结合,但我确信必须有一个更优雅和简洁的解决方案。

你有什么线索吗?
谢谢,
MZ

【问题讨论】:

  • format(Sys.Date(), "%Y-%U") 呢?
  • 几乎很可爱。改成format(Sys.Date(), "%y/%U",但显示今天还是w7,而应该是w8……这就是为什么我在lubricate包中使用isoweek而不是week的原因。
  • 我明白了。然而,嗯,isoweek(as.Date("2016-01-01"))53,而不是 1。那是你要的吗?因为在这种情况下,我只需修改 isoweek 函数以返回年份。
  • 我想要15/53,因为这是 2015 年的第 53 周。如果您尝试使用 isoweek(as.Date(2015-01-01)),您会发现在这种情况下它是第 1 周,所以我可以正常工作(就像它一样在 2015 年 12 月 31 日之前工作正常)。

标签: r lubridate


【解决方案1】:

如果您在 2018 年来到这里,请尝试来自 tsibble 的 yearweek

library(tsibble)
library(tidyverse)

my_date <- "2018-01-01"

yearweek(my_date) %>% 
  str_replace(" W", "/") %>% 
  str_replace("^20", "")

#> [1] 17/52

【讨论】:

【解决方案2】:

您可能需要调整 lubridate::isoweek 以返回所需的字符串:

isodate <- function (x = Sys.Date()) {
  xday <- ISOdate(year(x), month(x), day(x), tz = tz(x))
  dn <- 1 + (wday(x) + 5)%%7
  nth <- xday + ddays(4 - dn)
  jan1 <- ISOdate(year(nth), 1, 1, tz = tz(x))
  return(sprintf("%s/%02d", format(nth, "%y"), 1 + (nth - jan1)%/%ddays(7)))
}
isodate(as.Date("2016-01-01"))
# [1] "15/53"
isodate(as.Date("2015-01-01"))
# [1] "15/01"
isodate(Sys.Date())
# [1] "15/08"

【讨论】:

  • 哇,lukeA,这超出了我的编码技能,我会花几分钟时间了解更多关于您的解决方案的信息;尽管如此,这或多或少是我想要的备份解决方案(在 1 月 1 日的工作日工作),但到目前为止,我真的很困惑为什么这种“常见”(?)有用的功能还没有在某些包中得到解决或者还没有被问到。我是唯一对 ISO 版本的年和周感兴趣的人吗?
  • R 的好处:输入一个函数名——在本例中为isoweek——然后你就可以打印出它的源代码。然后我只是对其进行了一些修改,以便它返回您想要的结果。代码本身超出了我的“编码技能”,可能比你的还要多.... ;-)
  • 大声笑,对。没想到要看功能!!! :-) 非常感谢,卢克!
【解决方案3】:

使用lubridate包函数isoyear()结合isoweek(),可以得到你的问题的一条线答案。

library(stringr)
library(lubridate)

dates <- ymd(c("2016-01-01", "2015-12-31", "2015-01-01"))

# check dates[1] and dates[2] are in the same week
wday(dates)
#> [1] 6 5 5

str_c(
  formatC(isoweek(dates), format = "f", digits = 0, width = 2, flag = "0"), 
  "/", 
  str_sub(isoyear(dates), 3, 4))
#> [1] "53/15" "53/15" "01/15"

reprex package (v0.3.0) 于 2021-02-12 创建

【讨论】:

    【解决方案4】:

    isoweek() 替换为来自lubridate 的函数week()

    > paste(substr(year(x),3,4),sprintf("%02d", week(x)), sep="/")
    [1] "16/01"
    

    【讨论】:

    • 谢谢拉胡尔,但我真的需要isoweek。正如我在上面评论的那样,week 会给我一个“7”作为今天的日期,但是这个星期一是 ISO 第 8 周的第一天......
    猜你喜欢
    • 1970-01-01
    • 2018-06-08
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多