1

I am trying to add +1 to the cell value of certain cells in a raster. I have the cell numbers of the cells on which I'd like to perform said computation saved in a vector. I have a working code but with a large vector and raster it takes ages:

r <- raster(ncol=5,nrow=5)
r[] <- 0
vec <- c(1,1,1,3,4,5,6,7,8,8,8,9)
for(i in 1:length(vec))
      {
      r[vec[i]] <- r[vec[i]] + 1
      }

I have already tried to use r[vec] <- r[vec] + 1 but that doesn't work properly, it just sets the values of the cells stored in the vector to 1.

Does anybody know a faster way to do this ?

6
  • Just a few hints in the way. Generally, apply functions family are much faster than a for loop. Additionally, in your case I guess that you can use the foreach package and function to get the benefits of parallel processing.
    – dof1985
    Jul 10, 2016 at 19:35
  • Thanks for your comment. I know that loops are genrally slow, but in that case I couldn't think of any other solution. I also know about the foreach package and function but I haven't figured out how to aplly that on a raster. Could you maybe provide some example code ? Thanks again.
    – snoops
    Jul 10, 2016 at 19:48
  • Sorry. I have no practical experience with the foreach package. You can however try sapply(vec, function(x) { r[x] <<- r[x] +1 }). Check first on a subset to see if performance have improved.
    – dof1985
    Jul 10, 2016 at 20:01
  • Hope it works. I didn't try it myself
    – dof1985
    Jul 10, 2016 at 20:08
  • 1
    Why loop at all? r[vec] works fine
    – mdsumner
    Jul 10, 2016 at 20:18

1 Answer 1

1

Set the values via the index, once you tabulated it:

r <- raster(ncol=5,nrow=5)
r[] <- 0
vec <- c(1,1,1,3,4,5,6,7,8,8,8,9)
tab <- tabulate(vec, ncell(r))
r[vec] <- tab[vec]

That's wasteful for large rasters, but we need more details about how this needs to be done if that's a problem.

This is also a great example of how painful some basic things in R can be. For an efficient and straightforward solution, treat the "vec" as the cell index and do easy summary with dplyr (could do this in base R but I can't be bothered thinking):

library(magrittr) # for the use of piping %>%
library(dplyr)
cel <- data_frame(cell = vec)
tab <- cel %>% group_by(cell) %>% summarize(val = n())
## update your raster
r[tab$cell] <- tab$val

That will scale to very large grids and be efficient.

1
  • The magrittr edit is harmless, but pointless as the pipe op is re exported by dplyr.
    – mdsumner
    Jul 12, 2016 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.