Заменить все значения ячеек в растре из обновленных совокупных значений полигонов (т. е. обновить оценки численности населения, привязанные к сетке)

Цель: создать обновленный растр населения с координатной сеткой на 2023 год на основе растра населения с координатной сеткой 2020 года и полигональных оценок населения 2023 года.

Для этого я применил подход, пытаясь обновить все значения ячеек в растре новыми значениями ячеек, хранящимися в таблице по номеру ячейки.

У меня есть большой растр с оценками численности населения по сетке за 2020 год, полигонами округов и таблицей численности населения по округам в 2023 году. Я хотел бы обновить значения ячеек в растре 2020 года с тем же распределением/плотностью, но с учетом населения 2023 года.

Я начал со следующего:

  1. Используйте exactextractr::exact_extract, чтобы суммировать значения ячеек 2020 года (население) в каждом полигоне округа.
  2. Используйте terra:extract, чтобы извлечь все значения ячеек в растре 2020 года.
  3. Соединили 1 и 2, чтобы вычислить долю населения округа для каждой ячейки (т. е. значение ячейки/население округа).
  4. Соединил оценки численности населения округа на 2023 год с 3 и рассчитал новые значения ячеек, отражающие население округа 2023 года (население округа 2023 года * доля населения округа в каждой ячейке).
  5. Кажется, я не могу понять, как перенести новые значения ячеек в растр 2020 года.

У меня есть таблица с идентификатором округа, номером ячейки, старым значением ячейки и новым значением ячейки, но я не знаю, как обновить растр 2020 года новыми значениями. Если бы это был фрейм данных, я бы присоединился по номеру ячейки или просто напрямую присвоил новые значения, предполагая тот же порядок строк. Я просмотрел следующие статьи SO (и многие другие), но, похоже, они касаются только замены условного значения.

Ниже приведен несколько воспроизводимый пример (спасибо Зональной статистике R (растр/полигон) за общий растр и полигоны). Номера ячеек на шаге extract отображаются не так, как в реальных данных, но в остальном они очень похожи. В идеале я хотел бы присоединиться по номеру ячейки, чтобы иметь некоторое спокойствие и не зависеть от порядка строк.

library(terra)
library(exactextractr)
library(tidyverse)


# Create raster
ras <- raster(nrows=100, ncols=80, xmn=0, xmx=1000, ymn=0, ymx=800)
val <- runif (ncell(ras))
values(ras) <- val

# Create polygon within raster extent
xym <- cbind(runif (3,0,1000), runif (3,0,800))
p <- Polygons(list(Polygon(xym)),1)
sp <- SpatialPolygons(list(p))
spdf <- SpatialPolygonsDataFrame(sp, data=data.frame(1))

# Mask raster to within polygon
r2 <- mask(ras, spdf)

plot(r2)
lines(spdf)

#Create table of for new polygon value
new_tbl <- 
  tibble(X1 = 1,
         new_sum = 10000)

#1. Use ```extact_extractr::exact_extract``` to sum the 2020 cell values within each polygon.

poly_pop <- exact_extract(
  r2, 
  spdf, 
  fun = 'sum',
  weights = 'area',
  append_cols = T
) 

#2. Use ```terra:extract``` to extract all cell values in the old raster

r2_cell_values <- 
  terra::extract(
  r2, # raster file
  spdf, # polygons
  df = TRUE, 
  cells = TRUE, # Include cell numbers
  ID = TRUE,  # Include polygon IDs
  exact = TRUE # Include the proportion of the cell covered by the polygon
)

#3. Joined 1 and 2 to calculate the proportion of the value for each cell (i.e. cell value / polygon sum).

cell_props <-
r2_cell_values %>%
  filter(!is.na(layer)) %>% # Remove NA values
  left_join(poly_pop, by = c("ID" = "X1")) %>%
  mutate(
    cell_prop = layer / sum
  )

#4. Joined thenew values to 3 and calculated new cell values reflecting the mew polygon value (new polygon value * proportion of old polygon value in each cell)

new_cell_tbl <- 
cell_props %>%
  left_join(new_tbl, by = c("ID" = "X1")) %>%
  mutate(new_cell_value = cell_prop * new_sum)

#5. I can't seem to figure out how to get the new cell values into the 2020 raster. 

x <- rasterize(spdf, r2, 1)
cellStats(x, 'sum') == nrow(new_cell_tbl) # Check whether number of values in r2 and new_cell_tbl are the same

values(r2) <- new_cell_tbl$new_cell_value

В итоге я получаю следующее сообщение об ошибке: Error in setValues(x, value) : length(values) is not equal to ncell(x), or to 1, хотя я пытаюсь проверить, одинаково ли количество растровых ячеек и длина нового вектора на предыдущем шаге.

Я новичок в этом, поэтому буду признателен за любые рекомендации о том, как обновить ячейки 2020 года на основе значений административной области 2023 года. Спасибо!

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пример данных

library(terra)
pop <- rast(system.file("ex/elev.tif", package = "terra"))
names(pop) <- "pop2020"
adm <- vect(system.file("ex/lux.shp", package = "terra"))

Рассчитайте относительную численность населения на административную единицу для «2020 года».

adm <- extract(pop, adm, "sum", na.rm=TRUE, bind=TRUE)
pop_agg <- rasterize(adm, pop, "pop2020")
rel_pop <- pop / pop_agg

Используйте относительное распределение для вычисления количества ячеек растра для «2030 года».

#example data
adm$pop2030 <- adm$pop2020 * (1:12) / 2
# solution
new_pop <- rasterize(adm, pop, "pop2030") * rel_pop

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