将属性数据添加到分类栅格,在terra R中产生奇怪的结果

ajsxfq5m  于 2023-04-18  发布在  其他
关注(0)|答案(2)|浏览(141)

我有一个栅格数据,我已经分为3类。然后我想添加值到每个类。我使用以下代码

library(terra)

f <- system.file("ex/elev.tif", package="terra") 
r <- rast(f)

# classify the values into three groups
m <- c(min(global(r, "min", na.rm=TRUE)), 275, 1,
       275, 410, 2,
       410, max(global(r, "max", na.rm=TRUE)), 3)

#Reclassify the raster stack
rclmat <- matrix(m, ncol=3, byrow=TRUE)
rc <- classify(r, rclmat, include.lowest=TRUE)
plot(rc)

#Add some values to raster attribute table
rc$code <- c(0.002, 0.0056, 0.0124)

#Generate raster using the new column
y <- as.numeric(rc, 2)
plot(y)

如你所见,第二个情节很奇怪,我该怎么纠正它?

syqv5f0l

syqv5f0l1#

您的示例数据

library(terra)
r <- rast(system.file("ex/elev.tif", package="terra") )
m <- c(-Inf, 275, 1,
           275, 410, 2,
           410, Inf, 3)
rclmat <- matrix(m, ncol=3, byrow=TRUE)
rc <- classify(r, rclmat, include.lowest=TRUE)

要分配属性,必须使用levels(x)<-(请参见?levels)。您使用$<-,但这会创建一个新层。

levels(rc) <- data.frame(ID=1:3, code=c(0.002, 0.0056, 0.0124))
rc
#class       : SpatRaster 
#dimensions  : 90, 95, 1  (nrow, ncol, nlyr)
#resolution  : 0.008333333, 0.008333333  (x, y)
#extent      : 5.741667, 6.533333, 49.44167, 50.19167  (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat WGS 84 (EPSG:4326) 
#source(s)   : memory
#categories  : code 
#name        :   code 
#min value   :  0.002 
#max value   : 0.0124

如果您现在想将“代码”值放入单元格中,可以继续执行

y <- as.numeric(rc, 1)

(it应该是1而不是2,因为您只有一个类别。)
你也可以用

rc <- classify(r, rclmat, include.lowest=TRUE)
s <- subst(rc, 1:3, c(0.002, 0.0056, 0.0124))

但是如果这是你想要的输出,你应该在classify中使用这些值,这样你就可以一步完成。

m <- c(-Inf, 275, 0.002,  
        275, 410, 0.0056,
        410, Inf, 0.0124)

rclmat <- matrix(m, ncol=3, byrow=TRUE)
rc <- classify(r, rclmat, include.lowest=TRUE)

请注意,您可以进一步简化对classify的 * 原始 *(不是上面的那个)调用:

rc <- classify(r, c(-Inf, 275, 410, Inf), include.lowest=TRUE)
deyfvvtc

deyfvvtc2#

问题似乎是属性表中的类与栅格中的值范围不匹配(添加新值后)。我们可以通过首先使用classInt包中的classIntervals()函数计算连续数值变量的类间隔,然后为每个类赋值来保持匹配。

library(terra)
library(classInt)

f <- system.file("ex/elev.tif", package="terra") 
r <- rast(f)

# classify the values into three groups
m <- c(min(global(r, "min", na.rm=TRUE)), 275, 1,
       275, 410, 2,
       410, max(global(r, "max", na.rm=TRUE)), 3)

#Reclassify the raster stack
rclmat <- matrix(m, ncol=3, byrow=TRUE)
rc <- classify(r, rclmat, include.lowest=TRUE)
plot(rc)

# calculate class breaks/intervals 
brks <- classIntervals(values(rc), n=3, style="jenks")$brks

# assign values to classes based on class breaks/intervals
rc$code <- ifelse(values(rc) <= brks[2], 0.002,
                  ifelse(values(rc) <= brks[3], 0.0056, 0.0124))

#Generate raster using the new column
y <- as.numeric(rc, 2)
plot(y)

下面是一个扩展来展示我们如何调整brks[]

library(terra)
library(classInt)

f <- system.file("ex/elev.tif", package="terra") 
r <- rast(f)

# classify the values into three groups
m <- c(min(global(r, "min", na.rm=TRUE)), 275, 1,
       275, 410, 2,
       410, max(global(r, "max", na.rm=TRUE)), 3)

#Reclassify the raster stack
rclmat <- matrix(m, ncol=3, byrow=TRUE)
rc <- classify(r, rclmat, include.lowest=TRUE)
plot(rc)

# calculate class breaks/intervals 
brks <- classIntervals(values(rc), n=3, style="jenks")$brks

# assign values to classes based on class breaks/intervals
rc$code <- ifelse(values(rc) <= brks[3], 0.002,
                  ifelse(values(rc) <= brks[1], 0.0056, 0.0124))

#Generate raster using the new column
y <- as.numeric(rc, 2)
plot(y)

相关问题