admin管理员组文章数量:1403348
Using the terra package in R, I've got a raster and an associated attribute table that links the raster values to differently partitioned categories.
# generate a raster with values
set.seed(0)
raster_size <- 20
example_raster <- terra::rast(nrow=raster_size, ncols=raster_size)
example_raster_values <- sample(8, ncell(example_raster), replace=TRUE) # replace = TRUE to reuse values
values(example_raster) <- example_raster_values
# generate an attribute table with different categories and sub categories
example_attribute_table <-
data.frame(id = 1:8,
category1 = c("Haplic Acrisols", "Haplic Acrisols (Alumic)", "Haplic Acrisols (Ferric)", "Plinthic Acrisols", "Vetic Acrisols", "Haplic Albeluvisols", "Histic Albeluvisols", "Umbric Albeluvisols"),
category2 = c("Haplic Acrisols", "Haplic Acrisols", "Haplic Acrisols", "Plinthic Acrisols", "Vetic Acrisols", "Haplic Albeluvisols", "Histic Albeluvisols", "Umbric Albeluvisols"),
category3 = c("Acrisols", "Acrisols", "Acrisols", "Acrisols", "Acrisols", "Albeluvisols", "Albeluvisols", "Albeluvisols")
)
# substitute raster values
raster_cat1 <- terra::subst(example_raster, example_attribute_table$id, example_attribute_table$category1)
raster_cat2 <- terra::subst(example_raster, example_attribute_table$id, example_attribute_table$category2)
raster_cat3 <- terra::subst(example_raster, example_attribute_table$id, example_attribute_table$category3)
# stack rasters and change names
raster_stack <- c(example_raster, raster_cat1, raster_cat2, raster_cat3)
names(raster_stack) <- c("id", "category1", "category2", "category3")
I want to be able to plot (and post-process) these categories.
plot(raster_stack)
Note that id
and category1
are isomorphic (only renaming); category2
and category3
merge some of the ids
While this works, I find it surprisingly slow for large rasters (e. g. takes ~20 minutes for a 400 MB raster), considering it's conceptually no more than a renaming/merge of a few attributes.
I'm wondering if it's possible to make this much faster by using a different file format like geopackage, or by using categorical rasters. Maybe something that doesn't change the raster pixel by pixel, like terra::subst()
and terra::reclassify()
seem to do.
I was able to make this effectively "instantaneous" for the renaming case, i. e. when I plot this, the legend contains the labels of category1
(rather than those of id
).
levels(example_raster) <- example_attribute_table
plot(example_raster)
Are there any other fast options for renaming/merging categories?
Using the terra package in R, I've got a raster and an associated attribute table that links the raster values to differently partitioned categories.
# generate a raster with values
set.seed(0)
raster_size <- 20
example_raster <- terra::rast(nrow=raster_size, ncols=raster_size)
example_raster_values <- sample(8, ncell(example_raster), replace=TRUE) # replace = TRUE to reuse values
values(example_raster) <- example_raster_values
# generate an attribute table with different categories and sub categories
example_attribute_table <-
data.frame(id = 1:8,
category1 = c("Haplic Acrisols", "Haplic Acrisols (Alumic)", "Haplic Acrisols (Ferric)", "Plinthic Acrisols", "Vetic Acrisols", "Haplic Albeluvisols", "Histic Albeluvisols", "Umbric Albeluvisols"),
category2 = c("Haplic Acrisols", "Haplic Acrisols", "Haplic Acrisols", "Plinthic Acrisols", "Vetic Acrisols", "Haplic Albeluvisols", "Histic Albeluvisols", "Umbric Albeluvisols"),
category3 = c("Acrisols", "Acrisols", "Acrisols", "Acrisols", "Acrisols", "Albeluvisols", "Albeluvisols", "Albeluvisols")
)
# substitute raster values
raster_cat1 <- terra::subst(example_raster, example_attribute_table$id, example_attribute_table$category1)
raster_cat2 <- terra::subst(example_raster, example_attribute_table$id, example_attribute_table$category2)
raster_cat3 <- terra::subst(example_raster, example_attribute_table$id, example_attribute_table$category3)
# stack rasters and change names
raster_stack <- c(example_raster, raster_cat1, raster_cat2, raster_cat3)
names(raster_stack) <- c("id", "category1", "category2", "category3")
I want to be able to plot (and post-process) these categories.
plot(raster_stack)
Note that id
and category1
are isomorphic (only renaming); category2
and category3
merge some of the ids
While this works, I find it surprisingly slow for large rasters (e. g. takes ~20 minutes for a 400 MB raster), considering it's conceptually no more than a renaming/merge of a few attributes.
I'm wondering if it's possible to make this much faster by using a different file format like geopackage, or by using categorical rasters. Maybe something that doesn't change the raster pixel by pixel, like terra::subst()
and terra::reclassify()
seem to do.
I was able to make this effectively "instantaneous" for the renaming case, i. e. when I plot this, the legend contains the labels of category1
(rather than those of id
).
levels(example_raster) <- example_attribute_table
plot(example_raster)
Are there any other fast options for renaming/merging categories?
Share Improve this question edited Mar 20 at 12:47 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 20 at 12:33 MoehrengulaschMoehrengulasch 2411 silver badge10 bronze badges 01 Answer
Reset to default 1There is indeed no need to reclassify the raster cell values. You can set the categories table to the SpatRaster and then change the "active category" in a for-loop.
Your example data
library(terra)
set.seed(0)
r <- terra::rast(nrow=20, ncols=20)
values(r) <- sample(8, ncell(r), replace=TRUE)
att_table <- data.frame(
id = 1:8,
category1 = c("Haplic Acrisols", "Haplic Acrisols (Alumic)", "Haplic Acrisols (Ferric)", "Plinthic Acrisols", "Vetic Acrisols", "Haplic Albeluvisols", "Histic Albeluvisols", "Umbric Albeluvisols"),
category2 = c("Haplic Acrisols", "Haplic Acrisols", "Haplic Acrisols", "Plinthic Acrisols", "Vetic Acrisols", "Haplic Albeluvisols", "Histic Albeluvisols", "Umbric Albeluvisols"),
category3 = c("Acrisols", "Acrisols", "Acrisols", "Acrisols", "Acrisols", "Albeluvisols", "Albeluvisols", "Albeluvisols")
)
Solution
levels(r) <- att_table
par(mfrow=c(2,2))
for (i in 1:4) {
activeCat(r) <- i-1
plot(r, mar=c(1,1,0,10))
}
You can also do
levels(r) <- att_table
x <- rast(lapply(1:4, \(i) {activeCat(r) <- i-1; r}))
plot(x)
# extract values
x[9:10]
# id category1 category2 category3
#3 3 Haplic Acrisols (Ferric) Haplic Acrisols Acrisols
#6 6 Haplic Albeluvisols Haplic Albeluvisols Albeluvisols
But the most efficient way to extract all the attributes would be
e <- extract(r, 9:10, raw=TRUE)
# if the attributes are not ordered 1:n
# e <- match(e, att_table$id)
att_table[e,]
# id category1 category2 category3
#3 3 Haplic Acrisols (Ferric) Haplic Acrisols Acrisols
#6 6 Haplic Albeluvisols Haplic Albeluvisols Albeluvisols
本文标签: rFast renaming and merging of attributes for a rasterStack Overflow
版权声明:本文标题:r - Fast renaming and merging of attributes for a raster - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744409495a2604878.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论