#r #function #geospatial #spatial #r-raster
#r #функция #геопространственные #пространственный #r-растр
Вопрос:
Я хотел бы получить некоторую помощь, чтобы найти наилучший способ определения среднего количества осадков в нескольких странах на административном уровне. Я получил карты из
china<-raster::getData('GADM', country='CHN', level=1)
limits.dep<- raster::aggregate(china,'NAME_1')
и данные хранятся в файле .tiff.
data.rain<- function(year){
print(year)
dates <- seq(as.Date(paste0(year, "-01-01")), as.Date(paste0(year, "-01-31")), by="days")
dates <- gsub('-', '.', as.character(dates))
paths <- paste0(CHIRPS, year, '/', dates, '.tif.gz')
lapply(1:length(paths), function(k){
download.file(url = paths[k],
destfile = paste0('./', basename(paths[k])),
mode = 'wb')
})
}
CHIRPS <- 'https://data.chc.ucsb.edu/products/CHIRPS-2.0/global_daily/tifs/p05/'
data.rain(year=2020)
У меня много файлов (ежедневные данные), поэтому я также ищу что-то, что может работать для всех моих файлов.
Я нашел кое-что онлайн, что работает, но с большими наборами данных потребуется много времени, чтобы просто изменить файлы. Я менял формат с .tiff
на .asc
, но теперь, когда у меня больше дней, я не думаю, что это лучший способ сделать это.
Текущий код, который я использую, выглядит следующим образом
pacman::p_load(raster, rdgal, rgeos, stringr, sf, tidyverse, RColorBrewer, glue, cowplot, ggpubr, ggspatial, shadowtext)
china<-raster::getData('GADM', country='CHN', level=1)
limits.dep<- raster::aggregate(china,'NAME_1')
mps<- sf::st_as_sf(china)
# this are the results for each month
crn <- list.files('./data/chirps', full.names = TRUE, pattern = '.asc$') %>%
grep(paste0(c('januaryRain.asc','FebRain.asc','March.asc','April.asc','May.asc','Jun.asc','July.asc'),
collapse = '|'), ., value = TRUE) #%>%
stack() %>% #file are raster raster
raster::crop(., limits.dep) %>%
raster::mask(., limits.dep)
# had to run the function because I didn't know how to collect the monthly information from crn
makeDelta <- function(fls){
# fle <- fls[1]
ftr2 <- list.files(fls, full.names = TRUE) %>%
grep(paste0(c('januaryRain.asc','FebRain.asc','March.asc','April.asc','May.asc','Jun.asc','July.asc'),
#grep(paste0(c('rain.asc'),
collapse = '|'), ., value = TRUE) %>%
stack() %>%
raster::crop(., limits.dep) %>%
raster::mask(., limits.dep)
dfr <- crn ftr2-ftr2 #crn having the information that i need
return(dfr)
} # I also had to put each data set in different files in one folder and give them the same name
gcm <- list.files('./samename', full.names = FALSE) #folder
fls<- paste0('./samename/',gcm) #full path to each folder
dfr<-map(.x=fls,.f=makeDelta)
april <- lapply(1:length(dfr), function(k) dfr[[k]][[1]]) %>%
stack() %>%
mean()
feb <- lapply(1:length(dfr), function(k) dfr[[k]][[2]]) %>%
stack() %>%
mean()
jan <- lapply(1:length(dfr), function(k) dfr[[k]][[3]]) %>%
stack() %>%
mean()
july <- lapply(1:length(dfr), function(k) dfr[[k]][[4]]) %>%
stack() %>%
mean()
jun <- lapply(1:length(dfr), function(k) dfr[[k]][[5]]) %>%
stack() %>%
mean()
mar <- lapply(1:length(dfr), function(k) dfr[[k]][[6]]) %>%
stack() %>%
mean()
may <- lapply(1:length(dfr), function(k) dfr[[k]][[7]]) %>%
stack() %>%
mean()
mps$gid<-1:nrow(mps)
lyr.china <- raster::rasterize(as(mps, 'Spatial'), jan, field = 'gid')
#results for each province
znl_01 <- raster::zonal(jan, lyr.china, fun = 'mean') %>%
as_tibble(.) %>%
inner_join(., mps, by = c('zone' = 'gid')) %>%
dplyr::select(zone,mean, NAME_1, NL_NAME_1,TYPE_1,mean)
Если вы сможете улучшить этот код, это будет фантастически. Если вы знаете разные способы сделать это, я был бы очень благодарен за всю вашу помощь.
Комментарии:
1. Известно, что пакет растровых данных работает медленно, особенно когда вы маскируете растровые данные полигонами или растрируете полигоны. Двумя решениями являются (i) работа с пакетом terra , замена растрового пакета или (ii) растрирование полигонов с помощью пакета fasterize и только маскирование растровых объектов другими растровыми объектами того же формата и разрешения.
2. И независимо от этого, распараллеливание кода (например, foreach в сочетании со snow и doSNOW или parallel и doParallel ) обычно является хорошей идеей.