[R-sig-Geo] using the raster package to calculate knn results from yaImpute

Bastien.Ferland-Raymond at mrn.gouv.qc.ca Bastien.Ferland-Raymond at mrn.gouv.qc.ca
Tue Oct 29 15:31:10 CET 2013


Dear List,

I've been working on a way to make knn forest maps from satellite imagery and I'm using both the raster package (to prepare my data) and the yaImpute package (to do the knn).  The problem is that the yaImpute package requires data frames as inputs and I have rasters. So I have to do:

Raster -> data.frame -> knn -> data.frame -> raster

Which is not efficient.  I would like to be able to do directly:
Raster -> knn -> raster

Using the calc() fonction from the raster.  I've made a function that I thought would work however it doesn't, it gives me the error: "cannot use this function".  Any idea if my task is doable?

Here is a code example:

####
library(raster);library(yaImpute)

###  preparing the raster used as input:
r <- raster(nrow=50, ncol=50, xmn=0, xmx=50, ymn=0, ymx=50, crs=NA)
r.x1 <- r.x2 <- r.x3 <- r.x4 <- r.y1 <- r.y2 <- r
set.seed(123)
values(r.x1) <- rnorm(2500,10,1)
values(r.x2) <- rnorm(2500,13,1.1)
values(r.x3) <- rnorm(2500,20,5)
values(r.x4) <- rnorm(2500,.5,.05)
values(r.y1) <- rnorm(2500,10,1)
values(r.y2) <- rnorm(2500,50,5)
r.x.st <- stack(r.x1,r.x2,r.x3,r.x4)
names(r.x.st) <- c("varX1", "varX2","varX3","varX4")
r.y.st <- stack(r.y1,r.y2)
names(r.y.st) <- c("varY1", "varY2")
###


###  Making the table to use in yaImpute as reference observations
tab.x <- sampleRegular(r.x.st, 100, cells=T)        # choose the reference observations
rownames(tab.x) <- tab.x[,1]
tab.x <- tab.x[,-1]
tab.y <- sampleRegular(r.y.st, 100, cells=T)        # choose the reference observations
rownames(tab.y) <- tab.y[,1]
tab.y <- tab.y[,-1]
###


###  Praparing the knn (it's kind of a pre-knn that uses only the references set.
###  The object that it produces here is latter used on the target observations
res.yai <- yai(x=tab.x, y=tab.y, k=4, method="euclidean")
###


###  My function to get the prediction for a target observation
prod.knn.raster <-function(vec.bandes, info.yai, na.rm=T){
  dat <- rbind(vec.bandes,vec.bandes)                       # yaImpute needs a matrix as input (of usually at least 2 observations or it doesn't work)
  rownames(dat) <- c(paste0("o",round(runif(1,1,1000000000000000))),paste0("o",round(runif(1,1,1000000000000000)),"b"))  # it need a UNIQUE id for the pixel, there is maybe a way to use the cell number but I don't know it.
  res.knn.cible<-newtargets(info.yai,dat)                   # find the k nearest neighbours associated with the pixel of the raster
  res.imp <- impute.yai(res.knn.cible,observed=F)           # impute the values of the response variable for the pixel
  res <- res.imp [1,]                                       # keep one of the observations
  res                                                       # returns a vector of same length as the number of Y variables
}

### If I try my fonction directly it works
prod.knn.raster(vec.bandes=r.x.st[1], info.yai=res.yai, na.rm=T)
                   varY1    varY2
o87892296724022 11.17959 48.55119

### but if I put it in calc it doesn't:
qwqw <- calc(r.x.st, prod.knn.raster,info.yai=res.yai)
Error in .calcTest(x[1:5], fun, na.rm, forcefun, forceapply) :
  cannot use this function
####

I have a feeling the problem is linked with the fact I have to get the res.yai object into the function...

Anyway, thanks a lot for the potential help!


Bastien Ferland-Raymond, M.Sc. Stat., M.Sc. Biol.
Division des orientations et projets spéciaux
Direction des inventaires forestiers
Ministère des Ressources naturelles
880, chemin Sainte-Foy, 5e étage
Québec (Québec) G1S 4X4



More information about the R-sig-Geo mailing list