在 R 中为当前日期创建 year/week 格式
Creating a year/week format for current date in R
我写这篇文章 post 是因为我找不到其他已回答问题的讨论帖。
在 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
将 isoweek()
替换为 week()
,一个来自 lubridate 的函数。
> paste(substr(year(x),3,4),sprintf("%02d", week(x)), sep="/")
[1] "16/01"
您可能想要将 lubridate::isoweek
调整为 return 所需的字符串:
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"
如果您是 2018 年来到这里,请尝试 yearweek 来自 tsibble
library(tsibble)
library(tidyverse)
my_date <- "2018-01-01"
yearweek(my_date) %>%
str_replace(" W", "/") %>%
str_replace("^20", "")
#> [1] 17/52
使用 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 年 2 月 12 日创建
我写这篇文章 post 是因为我找不到其他已回答问题的讨论帖。
在 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
将 isoweek()
替换为 week()
,一个来自 lubridate 的函数。
> paste(substr(year(x),3,4),sprintf("%02d", week(x)), sep="/")
[1] "16/01"
您可能想要将 lubridate::isoweek
调整为 return 所需的字符串:
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"
如果您是 2018 年来到这里,请尝试 yearweek 来自 tsibble
library(tsibble)
library(tidyverse)
my_date <- "2018-01-01"
yearweek(my_date) %>%
str_replace(" W", "/") %>%
str_replace("^20", "")
#> [1] 17/52
使用 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 年 2 月 12 日创建