#r #gis #raster
#r #gis #растр
Вопрос:
У меня есть 200 растров с температурами воздуха на каждый день, хранящихся в каталоге, и я хотел бы получить совокупную сумму температур за каждый день, например, day1 = day1; day2 = day1 day2; day3 = day1 day2 day3 и т.д. Я пытался сделать это в raster
пакете, но cumsum
функция вычисляет совокупную сумму всех ячеек в каждом растре, а не совокупную сумму отдельных растров (по крайней мере, мне так кажется из моих результатов). Я попытался сделать это так:
library(raster)
setwd("C:/Air_temperatures/AT") # set working directory
AT.files <- list.files(pattern="AT") # list files with name AT
All.AT <- unique(AT.files) # unique files
for (i in 1:200) {
AT.i <- All.AT[i] # make i
AT.raster.i<-raster(AT.i) # make rasters from files
AT.sum.i <- cumsum(AT.raster.i) # ???calculate cumulative sum???
writeRaster(AT.sum.i,
paste(AT.i, "_cumsum.tif", sep = ""),
datatype='FLT4S', overwrite=TRUE) # write new files and paste new name
}
Этот цикл работал, когда я пытался, например, добавить константу к каждому растру и так далее, Но я понятия не имею, как рассчитать совокупную сумму.
Комментарии:
1. Не могли бы вы предоставить некоторые данные?
2. Я не уверен, как это сделать. Однажды я предоставил воспроизводимый пример, но не с растровыми данными. Каждый растр имеет ок. Размер 4 МБ.
Ответ №1:
Reduce
Здесь может помочь функция. Эта функция последовательно объединяет объекты на основе указанной функции. Поскольку существует
метод для Raster*
объектов, вы можете использовать его как функцию и получить совокупную сумму значений растра.
Сначала создайте 200 растровых объектов в списке:
theATs <- lapply(All.AT, raster)
Затем используйте Reduce
функцию с accumulate
аргументом, равным TRUE
res <- Reduce(" ", theATs, accumulate = TRUE)
Затем запишите результаты в файлы:
lapply(seq_along(res), function(x) {
writeRaster(res[[x]],
# Apparently, using .tif files threw an error
# paste(All.AT[x], "_cumsum.tif", sep = ""),
# Alternatively, omit file extension to write default type (usually .grd)
paste(All.AT[x], "_cumsum", sep = ""),
datatype = 'FLT4S', overwrite = TRUE)
})
Растры, которые вы создаете здесь, хранятся в памяти, поэтому, если исходные файлы очень большие, у вас могут возникнуть проблемы.
Комментарии:
1. Спасибо за ваш ответ. Но, как вы сказали, после нескольких минут вычисления
reduce
функции я получаю сообщение об ошибке:cannot allocate vector of size 8.4 Mb
есть какой-нибудь способ исправить эту проблему? Я попробовал это на 32-разрядной версии Windows XP Professional с 4 ГБ оперативной памяти.2. Хорошо, это R говорит, что у него закончилась память. В 32-разрядной Windows не так много места для маневра, но вы можете посмотреть, поможет ли увеличение лимита использования
memory.limit
. Если это не сработает, вы можете переписать свой цикл для чтения в ранее сохраненном растре (дляi > 1
), добавить текущие значения растра и сохранить сумму.3. Я попробовал это снова на Windows 7, 64 бит, 12 ГБ ОЗУ, и теперь
reduce
функция работает, но послеlapply
я получаю другую ошибку:Error in .gd_SetProject(transient, projection(r)) : STRING_ELT() can only be applied to a 'character vector', not a 'logical' Called from: top level Browse[1]>
у вас есть какие-либо предложения?4. @user3624251, я не видел этой ошибки, но в списке r-sig-geo есть поток, в котором упоминается проблема. Если это не поможет, боюсь, я достиг своих пределов.
5. Ваш подход работает, я только что удалил
.tif
изcumsum.tif
. Итак, теперь новые файлы находятся в.grd
формате, но я могу с этим смириться. Спасибо!