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 <jdnew...@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 <jdnew...@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 > > <jdnew...@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.salzmanu...@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.salzmanu...@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:<jdnew...@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 ______________________________________________ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.