Your first and third condition can be collapsed into one, which just leaves a single split point. As such, you can use ifelse.
year1 <- function(x) {
year <- as.numeric(format(x, "%Y"))
ifelse(x <= as.Date("1997-06-30"), year+6, year+7)
}
This is also vectorized, so you can use it like:
test <- as.Date(c("1985-09-15", "1999-02-15", "2004-08-15", "1996-02-15"))
year1(test)
which gives
> year1(test)
[1] 1991 2006 2011 2002
EDIT:
The code I gave was wrong; it did not agree with the original code in many of the cases. Here is an updated version which does:
year1 <- function(x){
year <- as.numeric(format(x, "%Y"))
ifelse(x <= as.Date("1997-06-30"),
year + 6,
ifelse(as.numeric(format(x, "%m")) >=07 ,
year + 7,
year + 6))
}
You can squeeze a little more out of it by not bothering with the assignment to year and factoring that out of the ifelse
year1 <- function(x){
as.numeric(format(x, "%Y")) +
ifelse(x <= as.Date("1997-06-30"),
6,
ifelse(as.numeric(format(x, "%m")) >=07 ,
7,
6))
}
Benchmarking:
year1.nzcoops <- function(x){
if(x <= as.Date("1996-12-31")) {out <- as.numeric(format(x, "%Y")) +6}
if(x >= as.Date("1997-07-01")) {ifelse(as.numeric(format(x, "%m")) >=07 , out <- as.numeric(format(as.Date(x), "%Y")) + 7, out <- as.numeric(format(x, "%Y")) + 6)}
if(x >= as.Date("1997-01-01") & x <= as.Date("1997-06-30")) {out <- 2003}
return(out)
}
year1.Brian <- function(x){
year <- as.numeric(format(x, "%Y"))
ifelse(x <= as.Date("1997-06-30"),
year + 6,
ifelse(as.numeric(format(x, "%m")) >=07 ,
year + 7,
year + 6))
}
year1.BrianB <- function(x){
as.numeric(format(x, "%Y")) +
ifelse(x <= as.Date("1997-06-30"),
6,
ifelse(as.numeric(format(x, "%m")) >=07 ,
7,
6))
}
year1.minopret <- function(dob) as.numeric(format(dob, "%Y")) + 6 +
(as.Date("1997-07-01") <= dob & 7 <= as.numeric(format(dob, "%m")))
More comprehensive test data:
test <- as.Date("1985-09-15")+(0:10000)
Checking results:
res.nzcoops <- sapply(test, year1.nzcoops)
res.Brian <- year1.Brian(test)
res.BrianB <- year1.BrianB(test)
res.minopret <- year1.minopret(test)
> identical(res.nzcoops, res.Brian)
[1] TRUE
> identical(res.nzcoops, res.BrianB)
[1] TRUE
> identical(res.nzcoops, res.minopret)
[1] TRUE
Timing comparisons:
> library("rbenchmark")
> benchmark(sapply(test, year1.nzcoops),
+ year1.Brian(test),
+ year1.BrianB(test),
+ year1.minopret(test),
+ order = "relative",
+ replications = 10)
test replications elapsed relative user.self
4 year1.minopret(test) 10 0.12 1.000000 0.12
3 year1.BrianB(test) 10 0.14 1.166667 0.14
2 year1.Brian(test) 10 0.16 1.333333 0.14
1 sapply(test, year1.nzcoops) 10 74.95 624.583333 74.85
sys.self user.child sys.child
4 0.00 NA NA
3 0.00 NA NA
2 0.01 NA NA
1 0.02 NA NA