I think this does what you want:
my.roll <- function(x) rollapply(x, 3, sd, align='right', fill=NA, na.rm=T)
z$sd <- ave(z$b, c(0, cumsum(diff(z$a) - 1)), FUN=my.roll)
Produces:
a b sd
1 1990 90 NA
2 1991 91 NA
3 1992 92 1
4 1993 93 1
5 1994 94 1
6 1995 95 1
7 1997 96 NA
8 1998 97 NA
9 1999 98 1
10 2001 99 NA
11 2002 100 NA
12 2003 101 1
Note how the first two entries after each gap are NA because you need at least three values in your window.
Basically, what we do here is use cumsum
and diff
to figure out the blocks of contiguous years, and then with that we can use ave
to apply sd
to each block. Note this will break if you have repeated years (e.g. 1997 shows up 2 or more times), or if your data isn't sorted by year.