[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