Search code examples
rdateformatdata-conversion

Converting date to year and week number and back


I want to convert a date to a combination of year and week number. Later I want to convert back to date again. I do not understand why it is not possible to arrive back at the same original date, even when I try all the different start of the week numbers:

library(dplyr)

df <- tidyr::expand_grid(
  date = as.Date(paste("2021 12 29"), "%Y %m %d") + 0:10,
  weekday = 0:6
)

df <- df %>%
  mutate(
    year = format(date, "%Y"),
    week = format(date, "%W"),
    newDate = as.Date(paste(year, week, weekday), format = "%Y %W %w")
  ) %>%
  tidyr::pivot_wider(
    id_cols = c("date"), names_from = "weekday", 
    values_from = "newDate"
  )

print(df)
# A tibble: 11 x 8
   date       `0`        `1`        `2`        `3`        `4`        `5`        `6`       
   <date>     <date>     <date>     <date>     <date>     <date>     <date>     <date>    
 1 2021-12-29 2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31 NA        
 2 2021-12-30 2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31 NA        
 3 2021-12-31 2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31 NA        
 4 2022-01-01 NA         NA         NA         NA         NA         NA         2022-01-01
 5 2022-01-02 NA         NA         NA         NA         NA         NA         2022-01-01
 6 2022-01-03 2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 2022-01-08
 7 2022-01-04 2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 2022-01-08
 8 2022-01-05 2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 2022-01-08
 9 2022-01-06 2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 2022-01-08
10 2022-01-07 2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 2022-01-08
11 2022-01-08 2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 2022-01-08

Why is there not a column that does not contains NAs?

Output of sessionInfo():

R version 3.6.2 (2019-12-12)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 17763)

Matrix products: default

locale:
[1] LC_COLLATE=English_United Kingdom.1252  LC_CTYPE=English_United Kingdom.1252   
[3] LC_MONETARY=English_United Kingdom.1252 LC_NUMERIC=C                           
[5] LC_TIME=English_United Kingdom.1252    

Solution

  • %G and %V solved my problem:

    library(dplyr)
    
    df <- tidyr::expand_grid(
      date = as.Date(paste("2021 12 26"), "%Y %m %d") + 0:10,
      weekday = 0:6
    )
    
    df <- df %>%
      mutate(
        year = format(date, "%G"),
        week = format(date, "%V"),
        newDate = as.Date(paste(year, week, weekday), format = "%Y %W %w")
      ) %>%
      tidyr::pivot_wider(
        id_cols = c("date", "year", "week"), names_from = "weekday", 
        values_from = "newDate"
      )
    
    print(df)
    # A tibble: 11 x 10
       date       year  week  `0`        `1`        `2`        `3`        `4`        `5`       
       <date>     <chr> <chr> <date>     <date>     <date>     <date>     <date>     <date>    
     1 2021-12-26 2021  51    2021-12-19 2021-12-20 2021-12-21 2021-12-22 2021-12-23 2021-12-24
     2 2021-12-27 2021  52    2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31
     3 2021-12-28 2021  52    2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31
     4 2021-12-29 2021  52    2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31
     5 2021-12-30 2021  52    2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31
     6 2021-12-31 2021  52    2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31
     7 2022-01-01 2021  52    2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31
     8 2022-01-02 2021  52    2021-12-26 2021-12-27 2021-12-28 2021-12-29 2021-12-30 2021-12-31
     9 2022-01-03 2022  01    2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07
    10 2022-01-04 2022  01    2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07
    11 2022-01-05 2022  01    2022-01-02 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07
    # ... with 1 more variable: 6 <date>