(This article was first published on

I am working with a model that produces estimates of snow water equivalent through time. Because I deal with large spatial extents, I decided to have the model produce weekly averages. The problem with this is knowing which file to access for a given date. The snow files are saved using an ISO-8061 week number (I had no idea how many date "standards" there were, but this is a common one). I thought that getting the week number out of a date format in R would be easy, but I was wrong. It turns out to be platform specific and regardless, as far as I could tell, there is no built-in way to calculate the ISO week. Thus the following function.**Quantitative Ecology**, and kindly contributed to R-bloggers)ISOweek<-function(date,format="%Y-%m-%d",return.val="weekofyear"){

##converts dates into "dayofyear" or "weekofyear", the latter providing the ISO-8601 week

##date should be a vector of class Date or a vector of formatted character strings

##format refers to the date form used if a vector of

## character strings is supplied

##convert date to POSIXt format

if(class(date)[1]%in%c("Date","character")){

date=as.POSIXlt(date,format=format)

}

if(class(date)[1]!="POSIXt"){

break

}else if(class(date)[2]=="POSIXct"){

date=as.POSIXlt(date)

}

if(return.val=="dayofyear"){

##add 1 because POSIXt is base zero

return(date$yday+1)

}else if(return.val=="weekofyear"){

##Based on the ISO8601 weekdate system,

## Monday is the first day of the week

## W01 is the week with 4 Jan in it.

year=1900+date$year

jan4=strptime(paste(year,1,4,sep="-"),format="%Y-%m-%d")

wday=jan4$wday

wday[wday==0]=7##convert to base 1, where Monday == 1, Sunday==7

##calculate the date of the first week of the year

weekstart=jan4-(wday-1)*86400

weeknum=ceiling(as.numeric((difftime(date,weekstart,units="days")+0.1)/7))

#########################################################################

##calculate week for days of the year occuring in the next year's week 1.

#########################################################################

mday=date$mday

wday=date$wday

wday[wday==0]=7

year=ifelse(weeknum==53 & mday-wday>=28,year+1,year)

weeknum=ifelse(weeknum==53 & mday-wday>=28,1,weeknum)

################################################################

##calculate week for days of the year occuring prior to week 1.

################################################################

##first calculate the numbe of weeks in the previous year

year.shift=year-1

jan4.shift=strptime(paste(year.shift,1,4,sep="-"),format="%Y-%m-%d")

wday=jan4.shift$wday

wday[wday==0]=7##convert to base 1, where Monday == 1, Sunday==7

weekstart=jan4.shift-(wday-1)*86400

weeknum.shift=ceiling(as.numeric((difftime(date,weekstart)+0.1)/7))

##update year and week

year=ifelse(weeknum==0,year.shift,year)

weeknum=ifelse(weeknum==0,weeknum.shift,weeknum)

return(list("year"=year,"weeknum"=weeknum))

}else{

break

}

}

Of course after I wrote this function, I found this thread in R-help. Gustaf Rydevik provided a function that is similar to mine (his function is also about twice as fast); however, on my computer it was giving incorrect years and week numbers for days in January that occur in the previous year's final week (e.g., 1 January 2010 should be week 53 of 2009). Reading through the rest of the thread indicates that the confusion involving week numbers is widespread. I guess the moral of the story is pick a standard and stick to it.

Please let me know in the comments if you encounter any problems running this function (or if you can suggest ways to make it more efficient).

To

**leave a comment**for the author, please follow the link and comment on his blog:**Quantitative Ecology**.R-bloggers.com offers

**daily e-mail updates**about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...