Search code examples
rtime-seriesr-rasterlinear-interpolation

returns an error


I need to substitute or interpolate the NA in a vector of each cell from a rasterstack data. I have two functions fun_sub for substituting NA and fun_interp for interpolating NA. I found fun_sub works very well. But fun_interp does not work but I cannot find a reason. Thank you very much

Tianyi Zhang

Below is a simple example:

#------EXAMPLE
library(timeSeries)
library(raster)
fun_sub <- function(x) {
  # substitute the NA to the mean of vector for each cell
v=as.vector(x)
z<-substituteNA(v,type="mean")
return (z)
}

fun_interp <- function(x) {
  # interpolate the NA to the the linear regression of vector for each cell
  v=as.vector(x)
  z=interpNA(v, method="linear")
  return (z)
}

# create data
r<-raster(ncols=2,nrows=2)
r1<-r; r2<-r; r3<-r; r4<-r
r1[]<-c(1,1,1,2)
r2[]<-c(5,5,NA,5)
r3[]<-c(3,3,4,2)
r4[]<-c(6,5,5,2)
s<-stack(r1,r2,r3,r4)

# try the two functions; the task is change the NA in r2 to a number;
res_sub<-calc(s,fun_sub) # works great! substitute the NA to the mean of    c(1,NA,4,5); I got c(1,3.333,4,5)
res_inter<-calc(s,fun_interp) # cannot interpolate; have an error, don't know the reason; I expected it is c(1, 2.5 ,4, 5). But it returns an error

# try whether interpNA() can work or not
interpNA(c(1,NA,4,5),method="linear") # but this function is OK.

Solution

  • I would go this way using standard functions:

    # create data
    library(raster)
    r1 <- r2 <- r3 <- r4 <-raster(ncol=2,nrow=2)
    r1[] <- c(1,1,1,2)
    r2[] <- c(5,5,NA,5)
    r3[] <- c(3,3,4,2)
    r4[] <- c(6,5,5,2)
    s < -stack(r1,r2,r3,r4)
    
    m <- mean(s, na.rm=TRUE)
    r_sub <- cover(s, m)
    r_int <- approxNA(s)
    
    values(s)
    ##     layer.1 layer.2 layer.3 layer.4
    ##[1,]       1       5       3       6
    ##[2,]       1       5       3       5
    ##[3,]       1      NA       4       5
    ##[4,]       2       5       2       2
    
    values(r_sub)
    ##     layer.1  layer.2 layer.3 layer.4
    ##[1,]       1 5.000000       3       6
    ##[2,]       1 5.000000       3       5
    ##[3,]       1 3.333333       4       5
    ##[4,]       2 5.000000       2       2
    
    values(r_int)
    ##     layer.1 layer.2 layer.3 layer.4
    ##[1,]       1     5.0       3       6
    ##[2,]       1     5.0       3       5
    ##[3,]       1     2.5       4       5
    ##[4,]       2     5.0       2       2
    

    To use the functions from the timeSeries package

    library(timeSeries)
    library(raster)
    

    New data .At least 6 cells needed for calc to test the function, that is an issue.

    r1 <- r2 <- r3 <- r4 <-raster(ncol=3,nrow=2)
    r1[] <- c(1,1,1,2,1,1)
    r2[] <- c(0,5,NA,5,1,1)
    r3[] <- c(3,3,4,2,1,1)
    r4[] <- c(6,5,5,2,1,1)
    s <- stack(r1,r2,r3,r4)
    
    values(s)
    values(calc(s, function(v) substituteNA(v,type="mean")))
    values(calc(s, function(v) interpNA(v, method="linear")))
    
    
    values(s)
    ##     layer.1 layer.2 layer.3 layer.4
    ##[1,]       1       0       3       6
    ##[2,]       1       5       3       5
    ##[3,]       1      NA       4       5
    ##[4,]       2       5       2       2
    ##[5,]       1       1       1       1
    ##[6,]       1       1       1       1
    
    values(calc(s, function(v) substituteNA(v,type="mean")))
    ##     layer.1  layer.2 layer.3 layer.4
    ##[1,]       1 0.000000       3       6
    ##[2,]       1 5.000000       3       5
    ##[3,]       1 3.333333       4       5
    ##[4,]       2 5.000000       2       2
    ##[5,]       1 1.000000       1       1
    ##[6,]       1 1.000000       1       1
    
    values(calc(s, function(v) interpNA(v, method="linear")))
    ##     layer.1 layer.2 layer.3 layer.4
    ##[1,]       1     0.0       3       6
    ##[2,]       1     5.0       3       5
    ##[3,]       1     2.5       4       5
    ##[4,]       2     5.0       2       2
    ##[5,]       1     1.0       1       1
    ##[6,]       1     1.0       1       1