Я новичок в R, и мне трудно разобраться в этой проблеме, поэтому буду благодарен за любую помощь. У меня есть ежедневные растровые данные о затоплении, которые я использую для расчета средневзвешенного значения затопления в буферах, созданных вокруг определенных мест. Я очистил растры в QGIS и использую R для расчета средневзвешенного значения с помощью следующих строк:
library(sp)
library(raster)
library(ggplot2)
library(sf)
# Load the raster file into R
flooding_raster_data <- raster(raster_file)
# Print information or perform further processing as needed
print(paste("Loaded raster file:", raster_file))
# Extract values from the raster that fall within the buffer polygons
raster_values_in_buffer_weight <- extract(flooding_raster_data, buffer, fun = mean, na.rm = TRUE, weights=TRUE)
# Create a new buffer object with the extracted floodshare values
buffer_with_mean <- st_as_sf(buffer)
buffer_with_mean$floodshare <- raster_values_in_buffer_weight
# Write the sf object to a shapefile
st_write(buffer_with_mean, output_file_path, append = FALSE)
rm(flooding_raster_data, buffer_with_mean, raster_values_in_buffer_weight, raster_file)
Моя проблема заключается в том, что для растра, где нет данных (закодированных как отсутствие данных в QGIS), среднее значение буферов равно 0. Я проверил это по зональному среднему значению в QGIS, и те же самые буферы имеют зональное среднее значение NULL в QGIS. Я изо всех сил пытаюсь понять, почему это произойдет в R, поскольку я думаю, что R будет иметь среднее значение NA или пропустить, поэтому, если кто-то знает, почему, пожалуйста, дайте мне знать и как я могу это исправить. Опять же, я новичок в R, поэтому, возможно, я упустил что-то очень очевидное.
Я попытался сделать na.rm = FALSE, потому что подумал, что, возможно, проблема была в том, как я обрабатывал значения NA в коде R, но это просто сделало все взвешенное среднее значение NULL, поэтому я думаю, что не понимаю, как R обрабатывает недостающие данные. .
РЕДАКТИРОВАТЬ
Я пошел проверить документацию по извлечению R и взял их пример кода, но изменил значения растра на NA, и это дает средневзвешенное значение, равное 0, для значений извлечения в виде полигонов, если все значения растра равны NA. Почему он не выдает NA для средневзвешенного значения, хотя все остальное дает ответ как NA или NaN. Я добавил код репликации ниже.
###############################
# extract values with lines
###############################
r <- raster(ncol=36, nrow=18, vals=NA)
cds1 <- rbind(c(-50,0), c(0,60), c(40,5), c(15,-45), c(-10,-25))
cds2 <- rbind(c(80,20), c(140,60), c(160,0), c(140,-55))
lines <- spLines(cds1, cds2)
extract(r, lines)
###############################
# extract values with polygons
###############################
cds1 <- rbind(c(-180,-20), c(-160,5), c(-60, 0), c(-160,-60), c(-180,-20))
cds2 <- rbind(c(80,0), c(100,60), c(120,0), c(120,-55), c(80,0))
polys <- spPolygons(cds1, cds2)
v <- extract(r, polys)
# mean for each polygon
mean_polyg <- unlist(lapply(v, function(x) if (!is.null(x)) mean(x, na.rm=TRUE) else NA ))
print(mean_polyg)
# weighted mean
v <- extract(r, polys, weights=TRUE, fun=mean, na.rm = TRUE)
print(v)
Возможно, вы хотите быть уверены в том, что представляют собой данные NA в вашем растровом объекте. Читается ли NA как 0 в R?
Если да, замените их:
flooding_raster_data <- raster(raster_file)
plot(flooding_raster_data) ## check 0 and NA values
raster_data[flooding_raster_data[] == 0] <- NA
plot(flooding_raster_data) ## check 0 and NA values
Проверьте, можно ли с помощью той (или другой) замены данных воспроизвести ожидаемые результаты.
Я думаю, что na.rm = TRUE справится с этим. Возможно ли, что для взвешенного среднего значения R создает буферы, которые имеют только значения NA, равные 0?
С октября 2023 года, когда они были признаны устаревшими, raster
и sp
создали ряд «причуд». Если вам не абсолютно необходимо их использовать, их лучше избегать. Я не могу точно сказать, является ли это результатом устаревания raster
и sp
, но вы можете добиться желаемого результата, используя пакеты terra
и sf
:
library(sf) # 1.0-16
library(terra) # terra 1.7.71
library(dplyr)
# Example sf to represent extent of example raster data and to use as mask
sf_poly <- st_read(system.file("shape/nc.shp", package = "sf")) %>%
slice(1) %>%
st_transform(4326) %>%
select(geometry)
# Get extent of sf_poly
st_bbox(sf_poly)
# xmin ymin xmax ymax
# -81.74091 36.23444 -81.23971 36.58973
# Generate an example raster with -Inf values using st_bbox(sf_poly) values
r <- rast(ncols = 50, nrows = 50, nlyrs = 1,
xmin = -81.74091, xmax = -81.23971,
ymin = 36.23444, ymax = 36.58973,
names = "rast_val",
crs = "EPSG:4326") %>%
init("cell") %>%
crop(sf_poly, mask = TRUE) %>%
ifel(is.na(.), -Inf, .)
# Create example polys sf (note id == 1 is outside extent of non-na/-Inf raster values)
polys <- data.frame(id = rep(1:4, each = 2),
lon = c(-81.7, -81.68, -81.6, -81.55, -81.4, -81.4, -81.3, -81.3),
lat = c(36.25, 36.33, 36.25, 36.40, 36.3, 36.55, 36.25, 36.36)) %>%
st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
summarise(geometry = st_combine(geometry), .by = id) %>%
st_cast("LINESTRING") %>%
st_buffer(800)
Теперь преобразуйте эти значения -Inf в NA (пропустите, если они уже являются NA в ваших фактических данных):
r <- ifel(r == -Inf, NA, r)
и, наконец, вычислите средневзвешенные значения для каждого многоугольника в полигонах:
v <- extract(r, polys, weights = TRUE, fun = mean, na.rm = TRUE)
v
# ID rast_val
# 1 1 NaN
# 2 2 1689.657
# 3 3 1169.131
# 4 4 1627.674
Ты прав! Я не использовал sp в своем коде, но использовал растровый пакет, который сам загружается в sp. В любом случае, я перешел на Терру и НФ, и это решило мою проблему. Интересно, что только взвешенные средние значения NULL экспортировались как 0, все остальные взвешенные средние такие же, как и раньше.
Итак, я проверил свой растр, и кажется, что мои значения NA равны -Inf