Добавление атрибутивных данных в классифицированный растр дает странные результаты в terra R

У меня есть растровые данные, которые я классифицировал на 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)

Как видите, второй сюжет странный. Как я могу это исправить?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
74
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема, похоже, в том, что классы в таблице атрибутов не соответствуют диапазону значений в растре (после добавления новых значений). Мы могли бы сохранить совпадение, сначала вычислив интервалы классов для непрерывных числовых переменных с помощью функции classIntervals() из пакета classInt, а затем присвоив значения каждому классу.

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)

Когда вы используете classIntervals на реклассифицированном растре, это меняет границы класса.

UseR10085 16.04.2023 10:31

Хорошо. Спасибо за ответ. Таким образом, возможно, что границы класса могут измениться в зависимости от конкретных правил реклассификации, которые вы используете. Но это явно выше моего понимания. Удачи!

TarJae 16.04.2023 11:30
Ответ принят как подходящий

Данные вашего примера

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)

(это должно быть 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)

Другие вопросы по теме