# How to make a loop that interates over large raster cells in R go faster?

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 ?

• 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. 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. 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. Jul 10, 2016 at 20:01
• Hope it works. I didn't try it myself Jul 10, 2016 at 20:08
• Why loop at all? r[vec] works fine Jul 10, 2016 at 20:18

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.

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