Search code examples
rtime-seriesinterpolationraster

R: Interpolation between raster layers of different dates


Let's say I have 4 raster layers with the same extend with data of 4 different years: 2006,2008,2010 and 2012:

library(raster)

r2006<-raster(ncol=3, nrow=3)
values(r2006)<-1:9

r2008<-raster(ncol=3, nrow=3)
values(r2008)<-3:11

r2010<-raster(ncol=3, nrow=3)
values(r2010)<-5:13

r2012<-raster(ncol=3, nrow=3)
values(r2012)<-7:15

Now I want to create raster layers for every year between 2006 and 2013 (or even longer) by inter-/extrapolating (a linear method should be a good start) the values of the 4 raster layers. The result should look like this:

r2006<-raster(ncol=3, nrow=3)
values(r2006)<-1:9

r2007<-raster(ncol=3, nrow=3)
values(r2007)<-2:10

r2008<-raster(ncol=3, nrow=3)
values(r2008)<-3:11

r2009<-raster(ncol=3, nrow=3)
values(r2009)<-4:12

r2010<-raster(ncol=3, nrow=3)
values(r2010)<-5:13

r2011<-raster(ncol=3, nrow=3)
values(r2011)<-6:14

r2012<-raster(ncol=3, nrow=3)
values(r2012)<-7:15

r2013<-raster(ncol=3, nrow=3)
values(r2013)<-8:16

Using lm() or approxExtrap don't seem to help a lot.


Solution

  • One way to do this is to separate your problem into two parts: 1. First, perform the numerical interpolation on the raster values, 2. and apply the interpolated values to the appropriate intermediate raster layers.

    Idea: Build a data frame of the values() of the raster layers, time index that data frame, and then apply Linear Interpolation to those numbers. For linear interpolation I use approxTime from the simecol package.

    For your example above,

    library(raster)
    library(simecol)    
    df <- data.frame("2006" = 1:9, "2008" = 3:11, "2010" = 5:13, "2012"=7:15)
    
    #transpose since we want time to be the first col, and the values to be columns
    new <- data.frame(t(df))
    times <- seq(2006, 2012, by=2)
    new <- cbind(times, new)
    
    # Now, apply Linear Interpolate for each layer of the raster
    approxTime(new, 2006:2012, rule = 2)
    

    This gives:

    #  times X1 X2 X3 X4 X5 X6 X7 X8 X9
    #1  2006  1  2  3  4  5  6  7  8  9
    #2  2007  2  3  4  5  6  7  8  9 10
    #3  2008  3  4  5  6  7  8  9 10 11
    #4  2009  4  5  6  7  8  9 10 11 12
    #5  2010  5  6  7  8  9 10 11 12 13
    #6  2011  6  7  8  9 10 11 12 13 14
    #7  2012  7  8  9 10 11 12 13 14 15
    

    You can then store this, and take each row and apply to the values of that year's raster object.

    Note: approxTime does not do linear extrapolation. It simply takes the closest value, so you need to account for that.