# ISO week

October 22, 2009
By

(This article was first published on Quantitative Ecology, and kindly contributed to R-bloggers)

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.

`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"){    print("Date is of wrong format.")    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{    print("Unknown return.val")    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).

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