How to extract data from a RasterBrick?

后端 未结 2 1526
误落风尘
误落风尘 2020-12-16 06:02

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\")
    >         


        
2条回答
  •  死守一世寂寞
    2020-12-16 06:35

    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.

提交回复
热议问题