3

Fisheries data is often collected by statistical weeks that start January 1st every year. The second week starts on the following Sunday each year.

So in 2013 Jan. 1st to Jan. 5 was week 1 and Jan. 6 to Jan.12 was week two. I am trying to calculate the statical week given a date for a number of years. My data is just dates in d-m-y format (i.e 16-6-1990) and I want a statistical week output in R code.

An example would be:

> d <- as.Date(c("01-01-2013","06-01-2013","01-01-2006","08-01-2006"),"%d-%m-%Y")

And the desired result would be:

> statweek(d)
[1] 1 2 1 2
thelatemail
  • 91,185
  • 12
  • 128
  • 188
Researcher
  • 39
  • 1
  • Welcome to SO. You should give [a reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – agstudy Jun 24 '13 at 23:56
  • Please use a title that is likely to help future searchers as well. How can your code/answer be useful to future searchers? If it can't then the question is likely to narrow and may get closed. – Tyler Rinker Jun 25 '13 at 00:00

2 Answers2

4

Try this:

> d <- as.Date("01-01-2013", "%d-%m-%Y") + 0:7  # first 8 days of 2013
> d
[1] "2013-01-01" "2013-01-02" "2013-01-03" "2013-01-04" "2013-01-05"
[6] "2013-01-06" "2013-01-07" "2013-01-08"
> 
> ufmt <- function(x) as.numeric(format(as.Date(x), "%U"))
> ufmt(d) - ufmt(cut(d, "year")) + 1
[1] 1 1 1 1 1 2 2 2

Note: The first Sunday in the year is defined as the start of week 1 by %U which means that if the year does not start on Sunday then we must add 1 to the week so that the first week is week 1 rather than week 0. ufmt(cut(d, "year")) equals one if d's year starts on Sunday and zero otherwise so the formula above reduces to ufmt(d) if d's year starts on Sunday and ufmt(d)+1 if not.

UPDATE: corrections so Jan starts at week 1 even if year starts on a Sunday, e.g. 2006.

G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • +1 Damn.... I didn't read far enough down in `strptime` to hit `%U` - nice answer. The simplest solution is always the best. – thelatemail Jun 25 '13 at 01:03
  • @thelatemail Your answer may not have been the best but if it worked and was reasonable why not leave it for other searchers to garner what they can. It hurts nothing in that the best answer will rise to the top anyway. – Tyler Rinker Jun 25 '13 at 01:29
  • 1
    @TylerRinker - I undeleted, and then realised it had issues anyway and redeleted. It did make me think some things through, so not all is lost ;-) – thelatemail Jun 25 '13 at 02:00
1

Here is the statweek function. The main argument can be a character vector of dates (the default after reading a data.frame, for example). You can specify the format of the dates (has a default: format="%d-%m-%Y")

d1 <- c("01-01-2013","06-01-2013","01-01-2006","08-01-2006") # format="%d-%m-%Y"
d2 <- c("01/01/2013","06/01/2013","01/01/2006","08/01/2006") # format="%d/%m/%Y"

statweek = function(dates, format="%d-%m-%Y", ...) {
  # convert to Date
  dates = as.Date(dates, format=format, ...) 
  # get correction for the first week of the year (0 if 1-Jan not a Sunday)
  firstweek = 1 - as.numeric(format(as.Date(cut(dates, "year")), "%U")) 
  output = as.numeric(format(dates, "%U")) + firstweek
  return(output)
}

And the examples:

statweek(d1)

[1] 1 2 1 2

statweek(d1, format="%d-%m-%Y")

[1] 1 2 1 2

statweek(d2, format="%d/%m/%Y")

[1] 1 2 1 2

Ricardo Oliveros-Ramos
  • 4,322
  • 2
  • 25
  • 42