UseR10085
UseR10085

Reputation: 8146

Multiple if-else for raster data in R

I have two raster as follows

library(raster)

a <- brick(ncol=100, nrow=100, nl=1)
set.seed(2)     
values(a) = runif(10000, min=-1, max=1)    # define the range between -1 and 1

b <- brick(ncol=100, nrow=100, nl=1)
set.seed(2)     
values(b) = runif(10000, min=25, max=35)

Now I want to create a new raster based on multiple conditions. The conditions are like

when a = 0 - 0.2, the new raster pixels should have the values of 1.5;

when a > 0.5, the new raster pixels should have the values of 1.85;

when 0.2 <= a <= 0.5, the new raster pixels should have the values of 1.70.

How to implement it in R?

Upvotes: 0

Views: 966

Answers (3)

Robert Hijmans
Robert Hijmans

Reputation: 47091

You can reclassify

library(raster)
a <- brick(ncol=100, nrow=100, nl=1)
set.seed(2)     
values(a) <- runif(ncell(a), min=0, max=1)   
m <- matrix(c(0, 0.2, 1.5, 0.2, 0.5, 1.7, 0.5, Inf, 1.85), ncol=3, byrow=TRUE)
x <- reclassify(a, m)

A less efficient way to get there, using cut (as SteveM used it)

y <- cut(a, c(0, 0.2, 0.5, 1))
z <- subs(y, data.frame(from=1:3, to=c(1.5, 1.7, 1.85)))

Val's solution works, but it is more for interactive exploration, not so much for use in a script.

Upvotes: 1

SteveM
SteveM

Reputation: 2301

You can use the cut function:

breaks <- c(-Inf, 0.2, 0.5, Inf)
labels <- c(1.5, 1.70, 1.85)
pixels <- cut(values(a), breaks = breaks, labels = labels)
pixels <- as.character(pixels)
pixels <- as.numeric(pixels)

pixels are converted to character first because converting the pixel factors to numeric directly rounds them to integers. There may be a cleaner way to do this.

BTW, here is a summary of values(a)

summary(values(a))
     layer          
 Min.   :-0.999954  
 1st Qu.:-0.500247  
 Median : 0.011779  
 Mean   : 0.006613  
 3rd Qu.: 0.506796  
 Max.   : 0.999927  

Note that there are negative values with a max of 0.999927, so not consistent with your defined break values.

Upvotes: 1

Val
Val

Reputation: 7023

As long as the your rasters are spatially identical, you can use simple boolean indexing:

# create empty copy
c <- raster(b)


c[(a >= 0) & (a < 0.2)] <- 1.5
c[(a >= 0.2) & (a <= 0.5)] <- 1.85
c[a > 0.5] <- 1.70

This works off an empty copy of b. If you want to keep the original values, you can use b instead of c

Upvotes: 1

Related Questions