lets take a grid of 3x4 rasters over three years in a silly calendar that only has seven months in it:
d = array(1:(3*4*7*3),c(3,4,7*3))
b = brick(d)
Now lets give the brick layers names by year and month:
names(b) = paste("rain",outer(1:7,2001:2003,paste,sep="-"),sep="-")
> names(b)
[1] "rain.1.2001" "rain.2.2001" "rain.3.2001" "rain.4.2001" "rain.5.2001"
[6] "rain.6.2001" "rain.7.2001" "rain.1.2002" "rain.2.2002" "rain.3.2002"
[11] "rain.4.2002" "rain.5.2002" "rain.6.2002" "rain.7.2002" "rain.1.2003"
[16] "rain.2.2003" "rain.3.2003" "rain.4.2003" "rain.5.2003" "rain.6.2003"
[21] "rain.7.2003"
and make some test points:
> pts = data.frame(x=runif(3),y=runif(3), month=c(5,1,3),year = c(2001,2001,2003))
> pts
x y month year
1 0.2513102 0.8552493 5 2001
2 0.4268405 0.3261680 1 2001
3 0.7228359 0.7607707 3 2003
Now construct the layer name for the points, and match to the names:
pts$layername = paste("rain",pts$month,pts$year,sep=".")
pts$layerindex = match(pts$layername, names(b))
Now I don't think the layer index in extract
is vectorised, so you have to do it in a loop...
> lapply(1:nrow(pts), function(i){extract(b, cbind(pts$x[i],pts$y[i]), layer=pts$layerindex[i], nl=1)})
[[1]]
rain.5.2001
[1,] 57
[[2]]
rain.1.2001
[1,] 5
[[3]]
rain.3.2003
[1,] 201
Or in a simple vector:
> sapply(1:nrow(pts), function(i){extract(b, cbind(pts$x[i],pts$y[i]), layer=pts$layerindex[i], nl=1)})
[1] 57 5 201
I'd do some checks to make sure those values are what you expect from those inputs before doing it on anything major though. Its easy to get indexes the wrong way round....
Another way to do it with a single extract
call is to compute the values for all layers and then extract with a 2-column matrix subset:
> extract(b, cbind(pts$x, pts$y))[
cbind(1:nrow(pts),match(pts$layername, names(b)))
]
[1] 57 5 201
Same numbers, comfortingly.