Unable to merge rasters that do not have unique ID values but DO have other unique attribute values

65 views Asked by At

I am attempting to merge many rasters together by a specific attribute (i.e., land cover) and NOT by the primary key index (i.e., OID) since the OID values are not unique to specific land covers among different rasters. When I attempt to merge rasters that have different amounts of land covers, only the first raster's values will be used. Furthermore, if the ID values align with different land covers, one raster's land cover value changes in the new merged raster. I have provided some example code and would appreciate any help, thanks!

Code Sample

library(terra)
set.seed(0)
rast1 <- rast(nrows=10, ncols=10)
values(rast1) <- sample(3, ncell(rast1), replace=TRUE)
d1 <- data.frame(id=1:3, cover=c("conifer", "water", "barren"), 
                  letters=letters[1:3])
levels(rast1) <- d1

rast2 <- rast(nrows=10, ncols=10)
values(rast2) <- sample(4, ncell(rast2), replace=TRUE)
d2 <- data.frame(id=1:4, cover=c("conifer", "water", "agriculture","barren"), 
                 letters=c("a","b","d","c"))
levels(rast2) <- d2

#Now try to merge rasters
Merge <- merge(rast1, rast2)

Issue: Merged raster only includes "cover" category from first raster input, and in the case with my data, non-unique ids are classified incorrectly into a different group. Here it would be that rast2's "agriculture" class is classified as "barren."

I have tried changing the raster levels manually, but that did not work.

1

There are 1 answers

3
Robert Hijmans On BEST ANSWER

That is a bit complex and perhaps "terra" should do that automatically. But for now you could do this with these two rasters

cat1 <- cats(r1)[[1]]
cat2 <- cats(r2)[[1]]

m <- match(cat1$cover, cat2$cover)
rc <- cbind(cat1$id, cat2$id[m])
r1c <- classify(r1, rc)
levels(r1c) <- levels(r2)

r12 <- merge(r1c, r2)

And if you have many rasters you may be able to use a loop like this. r2 is the most complete raster that we use as template.

x <- list(r2, r1)
mcat <- cats(r2)[[1]]

for (i in 2:length(x)) {
    r <- x[[i]]
    xcat <- cats(r)[[1]]
    m <- match(xcat$cover, mcat$cover)
    rc <- cbind(xcat$id, mcat$id[m])
    r <- classify(r, rc)
    levels(r) <- mcat
    x[[i]] <- r
}

s <- sprc(x)
m <- merge(s)