Совокупная сумма нескольких растров в R

#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 формате, но я могу с этим смириться. Спасибо!