MaZe
MaZe

Reputation: 259

Creating a year/week format for current date in R

I'm writing this post because I could find no other thread where the question was already answered.

What could be the best code to create a "y/w" format (y being a 2-digits year and w a 2 digits week number) in R?
So far, this is what I'm using:

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

But of course this could fail on the last days of the year or in the first ones; for example, it could give a "16/53" outcome for January, 1 of 2016 (while it should be "16/01").

I'm thinking about some if-else construct based on Sys.Date being higher or lower than January 1st and combining it with wday function, but I'm sure there must be a more elegant and concise solution.

Do you have any clue on that?
Thanks,
MZ

Upvotes: 5

Views: 12480

Answers (4)

josep maria porrà
josep maria porrà

Reputation: 1396

Using lubridate package function isoyear() combined with isoweek(), it is possible to obtain one-line answer to your question.

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"

Created on 2021-02-12 by the reprex package (v0.3.0)

Upvotes: 3

Vlad
Vlad

Reputation: 3774

If you're here in 2018, try yearweek from tsibble

library(tsibble)
library(tidyverse)

my_date <- "2018-01-01"

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

#> [1] 17/52

Upvotes: 8

lukeA
lukeA

Reputation: 54287

You might want to adjust lubridate::isoweek to return the desired string:

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"

Upvotes: 4

Rahul Premraj
Rahul Premraj

Reputation: 1595

Replace isoweek() with week(), a function from lubridate.

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

Upvotes: 0

Related Questions