I have a RasterBrick consisting of monthly rainfall data over 7 years, so it has 7 layers with 12 slots each:
rainfall <- brick(\"Rainfall.tif\")
>
Each layer in your RasterBrick
will have a unique name, so you can use match('name', names(b))
to find the numeric index of the layer you're interested in. Then use the layer=
argument to extract()
to point to the layer from which you'd like to extract (setting nl=1
to indicate that you only want that one layer).
Here's a reproducible example, in which I use cell numbers to do the extracting. (This will work exactly the same way when using SpatialPoints
to indicate which values are to be grabbed.)
## An example SpatialBrick
b <- brick(system.file("external/rlogo.grd", package="raster"))
nlayers(b)
# [1] 3
names(b)
# [1] "red" "green" "blue"
## Extract data from given cells in the "green" layer,
ii <- match("green", names(b))
extract(b, 1000:1003, layer=ii, nl=1)
# green
# [1,] 254
# [2,] 255
# [3,] 255
# [4,] 255
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.