How to extract data from a RasterBrick?

后端 未结 2 1429
误落风尘
误落风尘 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:12

    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
    
    0 讨论(0)
  • 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.

    0 讨论(0)
提交回复
热议问题