Reputation: 265
I am attempting to build an R-function that determines the "Day of the Water Year" similar to "Day of the Year" (DOY) functions through base R or other various packages (i.e. format(DATE,"%j")
). The water years can either start on October 1st or May 1st, therefore, the standard DOY functions do not work.
In this post and this webpage something akin to a "Day of Water Year" evaluation is performed. The major downfall is if you do have sequential dates, the sequential day index will be off and not the true "Day of Water Year". Is there a way to do this without using a date index?
Below is a very inefficient first step. Is there a way to optimize this or do it a different way that doesn't create an index based on day?
hydro.day=function(date,WY){
require(lubridate)
if(WY=="Fed"){jul.str=274};#"Federal" Water Year(WY) starts Oct 1
if(WY=="FL"){jul.str=121};#"State" Water Year(WY) starts May 1
doy.reg=data.frame(jul.day=c(seq(jul.str,365,1),
seq(1,jul.str-1,1)),hydro.day=seq(1,365,1))
doy.leap=data.frame(jul.day=c(seq(jul.str+1,366,1),
seq(1,jul.str,1)),hydro.day=seq(1,366,1))
hydro.day=data.frame()
for(i in 1:length(date)){
jul.day=as.numeric(format(date[i],"%j"))
leap=leap_year(date[i])
if(leap==F){tmp=merge(jul.day,doy.reg,by.x="x",by.y="jul.day")}
else{tmp=merge(jul.day,doy.leap,by.x="x",by.y="jul.day")}
hydro.day=rbind(hydro.day,tmp)
}
return(hydro.day$hydro.day)
}
Any help would be appreciated.
Upvotes: 2
Views: 769
Reputation: 31452
This should do it:
library(lubridate)
hydro.day.new = function(x, start.month = 10L){
start.yr = year(x) - (month(x) < start.month)
start.date = make_date(start.yr, start.month, 1L)
as.integer(x - start.date + 1L)
}
Testing it out:
set.seed(123)
x = as.Date(as.POSIXct(sample(5000,10)*60*60*24, origin = "2000-01-01", tz = "GMT"))
hydro.day.new(x)
# [1] 70 16 311 123 43 321 174 166 289 180
hydro.day(x, "Fed")
# [1] 70 16 311 123 43 321 174 166 289 180
Upvotes: 2