Цель: создать обновленный растр населения с координатной сеткой на 2023 год на основе растра населения с координатной сеткой 2020 года и полигональных оценок населения 2023 года.
Для этого я применил подход, пытаясь обновить все значения ячеек в растре новыми значениями ячеек, хранящимися в таблице по номеру ячейки.
У меня есть большой растр с оценками численности населения по сетке за 2020 год, полигонами округов и таблицей численности населения по округам в 2023 году. Я хотел бы обновить значения ячеек в растре 2020 года с тем же распределением/плотностью, но с учетом населения 2023 года.
Я начал со следующего:
exactextractr::exact_extract
, чтобы суммировать значения ячеек 2020 года (население) в каждом полигоне округа.terra:extract
, чтобы извлечь все значения ячеек в растре 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 года. Спасибо!
Пример данных
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