# [R] year and week to date - before 1/1 and after 12/31

peter salzman peter@@@|zm@nu@er @end|ng |rom gm@||@com
Thu Oct 18 15:19:25 CEST 2018

thanks Jeff and Gabor,
appreciate you spending time on this,

you both use similar ideas - add/subtract days/weeks from a day that exists

combining all i learned i would go with something like this:

## step 1) find 1st sunday of year Y
d11 <- as.Date( sprintf( "%04d 1 1"
, DF[[ "Y" ]]
)
, format = "%Y %U %u"
)
## btw note that when Jan 1 is on sunday then d11 will be Jan 8th
## step 2) for start of week just add the number of weeks that is needed
start <- d11 + (w-1)*week
## step 3) for end of week add number of weeks and subtract 1 day
start <- d11 + w*week - day

thanks
peter

On Wed, Oct 17, 2018 at 11:15 PM Jeff Newmiller
<jdnewmil using dcn.davis.ca.us> wrote:
>
> You cannot obtain a predictable result by sending invalid time
> representation data to strptime... you have to work with valid time
> representations.
> See sample approach below:
>
> ############################
> weekEnds <- function( DF ) {
>     d1_1 <- as.Date( sprintf( "%04d 1 1"
>                             , DF[[ "Y" ]]
>                             )
>                    , format = "%Y %U %u"
>                    )
>     d52_7 <- as.Date( sprintf( "%04d 52 7"
>                              , DF[[ "Y" ]]
>                              )
>                     , format = "%Y %U %u"
>                     )
>     week <- as.difftime( 7, units = "days" )
>     day <- as.difftime( 1, units = "days" )
>     d <- as.Date( sprintf( "%04d %d 1"
>                          , DF[[ "Y" ]]
>                          , DF[[ "wn" ]]
>                          )
>                 , format = "%Y %U %u"
>                 )
>     before <- 0 == DF[[ "wn" ]]
>     after <- 53 == DF[[ "wn" ]]
>     d[ before ] <- d1_1[ before ] - week
>     d[ after ] <- d52_7[ after ] + day
>     DF[[ "weekBegin" ]] <- d
>     DF[[ "weekEnd" ]] <- d + week
>     DF
> }
>
> tst <- expand.grid( Y = 2000:2028
>                    , wn = c( 0, 1, 53 )
>                    )
>
> result <- weekEnds( tst )
> set.seed( 42 )
> result[ sample( nrow( result ), 5 ), ]
> #>       Y wn  weekBegin    weekEnd
> #> 80 2021 53 2021-12-27 2022-01-03
> #> 81 2022 53 2022-12-26 2023-01-02
> #> 25 2024  0 2024-01-01 2024-01-08
> #> 70 2011 53 2011-12-26 2012-01-02
> #> 54 2024  1 2024-01-08 2024-01-15
> sum( is.na( result\$weekBegin ) )
> #> [1] 0
> ############################
>
> On Tue, 16 Oct 2018, peter salzman wrote:
>
> > hi,
> > thanks for replying,
> >
> > it has taken some time to understand
> >
> > i have year+week and i need to find the 1st day and the last day of that week
> > i can decide when week starts
> >
> > for example these 3 examples:
> > df <- data.frame(id = 1:3, year = c(2018, 2018, 2018), week=c(0,1,52))
> >
> > ## now run for all 3 rows:
> > for (kk in 1:3) {
> >   print(df[kk,])
> >   print('## version 1')
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'Sun',sep=' '), format = "%Y %U %a")       )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'Mon',sep=' '), format = "%Y %U %a")       )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'Tue',sep=' '), format = "%Y %U %a")       )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'Wed',sep=' '), format = "%Y %U %a")       )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'Thu',sep=' '), format = "%Y %U %a")       )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'Fri',sep=' '), format = "%Y %U %a")       )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'Sat',sep=' '), format = "%Y %U %a")       )
> >
> >   print('## version 2')
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'7',sep=' '), format = "%Y %U %u")        )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'1',sep=' '), format = "%Y %U %u")         )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'2',sep=' '), format = "%Y %U %u")         )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'3',sep=' '), format = "%Y %U %u")         )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'4',sep=' '), format = "%Y %U %u")         )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'5',sep=' '), format = "%Y %U %u")         )
> >   print(as.Date(paste(df\$year[kk],df\$week[kk],'6',sep=' '), format = "%Y %U %u")         )
> > }
> >
> > for week 0 we get NA for Sunday because it was Dec 31, 2017
> > similarly for week 52 we get NA for Tue,Wed, ... because these are in January of 2019
> >
> > my hope was to write
> > as.Date(paste(year,week,1), format "%Y %month %weekday")
> > as.Date(paste(year,week,7), format "%Y %month %weekday")
> > and get the first and last day of the given week even at the beginning and end of year
> > for example
> > as.Date("2018 0 Sun","%Y %U %a")   = '2017-12-31'
> >
> > i hope this makes sense.
> >
> > thanks for replying
> > peter
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On Tue, Oct 16, 2018 at 2:11 PM Jeff Newmiller <jdnewmil using dcn.davis.ca.us> wrote:
> >       Er, my mistake, you are using %U not %W... but now I am really confused, because the first Sunday is trivial with %U/%u.
> >
> >       Can you clarify what your actual upstream input is? Is it an invalid date string as you say below, or is it year number?
> >
> >       On October 16, 2018 10:22:10 AM PDT, Jeff Newmiller <jdnewmil using dcn.davis.ca.us> wrote:
> >       >If the date in your character representation does not exist then there
> >       >is no requirement for a POSIX function to give any reliable answer...
> >       >including NA. Using 00 as the week number won't always work.
> >       >
> >       >The first week/weekday combination that is guaranteed to exist by POSIX
> >       >is 1/1 (first Monday). If the corresponding mon/mday is 1/1 then no
> >       >days exist in week zero for that year and the first Sunday is 6 days
> >       >more than the mday of the first Monday, else the mday of the first
> >       >Sunday is one day less than the mday of the first Monday.
> >       >
> >       >You should if at all possible repair the computations that are creating
> >       >the invalid string dates you mention.
> >       >
> >       >On October 16, 2018 8:11:12 AM PDT, peter salzman
> >       ><peter.salzmanuser using gmail.com> wrote:
> >       >>it is simpler than i thought
> >       >>
> >       >>first day of given week is the last day minus 6days
> >       >>
> >       >>in other words:
> >       >>d1 = as.Date('2018 00 Sat',format="%Y %U %a") - 6
> >       >>d2 = as.Date('2018 00 Sun',format="%Y %U %a")
> >       >>are the same as long both are not NA
> >       >>
> >       >>therefore to get the one that is not NA one can do
> >       >>
> >       >>max( c(d1,d2), na.rm=TRUE )
> >       >>
> >       >>maybe there is some other trick
> >       >>
> >       >>best,
> >       >>peter
> >       >>
> >       >>
> >       >>
> >       >>
> >       >>
> >       >>
> >       >>On Tue, Oct 16, 2018 at 10:22 AM peter salzman
> >       >><peter.salzmanuser using gmail.com>
> >       >>wrote:
> >       >>
> >       >>> hi,
> >       >>>
> >       >>> to turn year and week into the date one can do the following:
> >       >>>
> >       >>> as.Date('2018 05 Sun', "%Y %W %a")
> >       >>>
> >       >>> however, when we want the Sunday (1st day of week) of the 1st week
> >       >of
> >       >>2018
> >       >>> we get NA because 1/1/2018 was on Monday
> >       >>>
> >       >>> as.Date('2018 00 Mon',format="%Y %U %a")
> >       >>> ## 2018-01-01
> >       >>> as.Date('2018 00 Sun',format="%Y %U %a")
> >       >>> ## NA
> >       >>>
> >       >>> btw the same goes for last week
> >       >>> as.Date('2017 53 Sun',format="%Y %U %a")
> >       >>> ## 2017-12-31
> >       >>> as.Date('2017 53 Mon',format="%Y %U %a")
> >       >>> ## NA
> >       >>>
> >       >>> So my question is :
> >       >>> how do i get
> >       >>> from "2018 00 Sun" to 2018-12-31
> >       >>> and
> >       >>> from "2017 53 Mon" to 2018-01-01
> >       >>>
> >       >>> i realize i can loop over days of week and do some if/then
> >       >>statements,
> >       >>> but is there a built in function?
> >       >>>
> >       >>> thank you
> >       >>> peter
> >       >>>
> >       >>>
> >       >>>
> >       >>>
> >       >>>
> >       >>> --
> >       >>> Peter Salzman, PhD
> >       >>> Department of Biostatistics and Computational Biology
> >       >>> University of Rochester
> >       >>>
> >
> >       --
> >       Sent from my phone. Please excuse my brevity.
> >
> >
> >
> > --
> > Peter Salzman, PhD
> > BMS
> > Greater Boston Area, MA
> >
> >
>
> ---------------------------------------------------------------------------
> Jeff Newmiller                        The     .....       .....  Go Live...
> DCN:<jdnewmil using dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
>                                        Live:   OO#.. Dead: OO#..  Playing
> Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
> /Software/Embedded Controllers)               .OO#.       .OO#.  rocks...1k
> ---------------------------------------------------------------------------

--
Peter Salzman, PhD
BMS
Greater Boston Area, MA

More information about the R-help mailing list