If you can do this on a vector you can do this on a raster.
To do this on a vector, first set up a test vector so you can see if it works.
x = c(0, 1, 2, 3, NA, 5, 5.1, NA, 6, 7)
if I understand the first part, anything >= 5.1 becomes 1, anything less than is scaled by 5.1. That's this:
ifelse(x>=5.1, 1, x/5.1)
which looks like this:
[1] 0.0000000 0.1960784 0.3921569 0.5882353 NA 0.9803922 1.0000000
[8] NA 1.0000000 1.0000000
and now we ifelse
on the NAs to set them to 0.000001:
> ifelse(is.na(x),.000001, ifelse(x>=5.1, 1, x/5.1))
[1] 0.0000000 0.1960784 0.3921569 0.5882353 0.0000010 0.9803922 1.0000000
[8] 0.0000010 1.0000000 1.0000000
bit hard to tell how everything has mapped there so let's combine it with the original:
> cbind(x, ifelse(is.na(x),.000001, ifelse(x>=5.1, 1, x/5.1)))
x
[1,] 0.0 0.0000000
[2,] 1.0 0.1960784
[3,] 2.0 0.3921569
[4,] 3.0 0.5882353
[5,] NA 0.0000010
[6,] 5.0 0.9803922
[7,] 5.1 1.0000000
[8,] NA 0.0000010
[9,] 6.0 1.0000000
[10,] 7.0 1.0000000
that all looks good.
To work this on a raster you can treat r[]
as the vector of values in the raster. Let's make an example from x
:
> r = raster(matrix(x, ncol=2))
so thats a 2x5 raster:
> as.matrix(r)
[,1] [,2]
[1,] 0 5.0
[2,] 1 5.1
[3,] 2 NA
[4,] 3 6.0
[5,] NA 7.0
then use r[]
everywhere we had x
and replace the values in r
:
> r[] = ifelse(is.na(r[]),.000001, ifelse(r[]>=5.1, 1, r[]/5.1))
giving:
> as.matrix(r)
[,1] [,2]
[1,] 0.0000000 0.9803922
[2,] 0.1960784 1.0000000
[3,] 0.3921569 0.0000010
[4,] 0.5882353 1.0000000
[5,] 0.0000010 1.0000000
Learning outcomes: R can work on entire vectors and is a zillion times faster when you do that instead of for
loops; you can make a reproducible example even if you can't dish out the data; make small examples so you can verify by eye that your code works; rasters are vectors - if you can do something on a vector in R you can do it on a raster.