вычислить медиану нескольких растровых файлов разной степени

Я новичок в R, и у меня есть проблема, решение которой я пока не нашел. У меня есть папка из 1000 растровых файлов. Мне нужно получить медиану всех растров для каждой ячейки.

Файлы содержат ячейки NoData (я думаю, поэтому они имеют разные размеры). Есть ли какое-либо решение для циклического просмотра папки, сложения всех файлов и получения медианы?

Error in rep(value, times = ncell(x)) : invalid 'times' argument
In addition: Warning message:
In setValues(x, rep(value, times = ncell(x))) : NAs introduced by coercion
Error in .local(x, i, j, ..., value) : 
  cannot replace values on this raster (it is too large

Я пробовал использовать растровый стек, но он не работает из-за разных экстентов.
Спасибо за помощь.


person user3327377    schedule 19.02.2014    source источник
comment
Иметь NoData и иметь разные экстенты — это две разные вещи. Экстент указывает расположение левого, правого, верхнего и нижнего краев прямоугольника, а ячейки внутри этого прямоугольника могут содержать или не содержать значения NoData. Если файлы имеют разные экстенты, хотите ли вы вычислить медианы только в областях, общих для всех файлов (т. е. на пересечении всех растров)?   -  person jbaums    schedule 19.02.2014
comment
Следующий вопрос: идентичны ли выравнивания растров? то есть выравниваются ли края растра друг с другом?   -  person jbaums    schedule 19.02.2014
comment
Разве вы не можете: создать растр для общего экстента, наложить каждый растр на растр общего экстента (умножить), создать стек растра и запустить calc с медианой в качестве функции?   -  person Paulo E. Cardoso    schedule 20.02.2014


Ответы (1)


Я попытаюсь подойти к этому с помощью mosaic() изображений с разным размером и происхождением, но с одинаковым разрешением.

Создайте несколько объектов rasterLayer и экспортируйте их (чтобы прочитать последний)

library('raster')
library('rgdal')

e1 <- extent(0,10,0,10)
r1 <- raster(e1)
res(r1) <- 0.5
r1[] <- runif(400, min = 0, max = 1)
#plot(r1)

e2 <- extent(5,15,5,15)
r2 <- raster(e2)
res(r2) <- 0.5
r2[] <- rnorm(400, 5, 1)
#plot(r2)

e3 <- extent(18,40,18,40)
r3 <- raster(e3)
res(r3) <- 0.5
r3[] <- rnorm(1936, 12, 1)
#plot(r3)

# Write them out
wdata <- '../Stackoverflow/21876858' # your local folder
writeRaster(r1, file.path(wdata, 'r1.tif'),
            overwrite = TRUE)
writeRaster(r2,file.path(wdata, 'r2.tif'),
            overwrite = TRUE)
writeRaster(r3,file.path(wdata, 'r3.tif'),
            overwrite = TRUE)

Чтение и мозаика с функцией

Поскольку raster::mosaic не принимает rasterStack/rasterBrick или списки rasterLayers, лучшим подходом является использование do.call, например отличный пример.

Для этого настройте сигнатуру мозаики и способ вызова ее аргументов с помощью:

setMethod('mosaic', signature(x='list', y='missing'), 
          function(x, y, fun, tolerance=0.05, filename=""){
            stopifnot(missing(y))
            args <- x
            if (!missing(fun)) args$fun <- fun
            if (!missing(tolerance)) args$tolerance<- tolerance
            if (!missing(filename)) args$filename<- filename
            do.call(mosaic, args)
          })

Давайте сохраним низкую терпимость здесь, чтобы оценить любое неправильное поведение нашей функции.

Наконец, функция:

Функция мозаики

f.Mosaic <- function(x=x, func = median){
  files <- list.files(file.path(wdata), all.files = F)
  # List  TIF files at wdata folder
  ltif <- grep(".tif$", files, ignore.case = TRUE, value = TRUE) 
  #lext <- list()
  #1rt <- raster(file.path(wdata, i),
  #            package = "raster", varname = fname, dataType = 'FLT4S')
  # Give an extent area here (you can read it from your first tif or define manually)
  uext <- extent(c(0, 100, 0, 100)) 
  # Get Total Extent Area
  stkl <- list()
  for(i in 1:length(ltif)){
    x <- raster(file.path(wdata, ltif[i]),
                package = "raster", varname = fname, dataType = 'FLT4S')
    xext <- extent(x)
    uext <- union(uext, xext)
    stkl[[i]] <- x
  }
  # Global Area empty rasterLayer
  rt <- raster(uext)
  res(rt) <- 0.5
  rt[] <- NA
  # Merge each rasterLayer to Global Extent area
  stck <- list()
  for(i in 1:length(stkl)){
    merged.r <- merge(stkl[[i]], rt,  tolerance = 1e+6)
    #merged.r <- reclassify(merged.r, matrix(c(NA, 0), nrow = 1))
    stck[[i]] <- merged.r
  }
  # Mosaic with Median
  mosaic.r <- raster::mosaic(stck, fun = func) # using median
  mosaic.r
}
# Run the function with func = median
mosaiced <- f.Mosaic(x, func = median)
# Plot it
plot(mosaiced)

мозаичный растр с медианой

Возможно, далеко не лучший подход, но надеюсь, что это поможет.

person Paulo E. Cardoso    schedule 21.02.2014
comment
Большое спасибо за помощь! К сожалению, я получил сообщение об ошибке, но не могу найти, где оно находится: Ошибка в rep(value, times = ncell(x)) : неверный аргумент 'times' Кроме того: Предупреждающее сообщение: In setValues(x, rep(value, times = ncell(x))) : NA, введенные принудительным принуждением. Ошибка в .local(x, i, j, ..., value): невозможно заменить значения в этом растре (он слишком велик, есть идеи? Еще раз спасибо - person user3327377; 27.02.2014
comment
вы экспортировали r2 и r3 в самом начале # Write them out? Я только что написал код для первого... - person Paulo E. Cardoso; 28.02.2014
comment
@ user3327377 не могли бы вы предоставить некоторые из ваших растров? Я не понял, используете ли вы свои данные или воспроизводите приведенный выше код. - person Paulo E. Cardoso; 28.02.2014
comment
Я пытаюсь запустить его на своих собственных данных. - person user3327377; 28.02.2014
comment
@user3327377 user3327377, не могли бы вы поделиться своим растром из Dropbox или GoogleDrive? - person Paulo E. Cardoso; 28.02.2014
comment
Я не думаю, что это необходимо, потому что это сработало! Очевидно, я загрузил не тот экстент... большое спасибо за помощь, Пауло! - person user3327377; 28.02.2014
comment
@user3327377. Большой! Не забудьте проголосовать за ответ, если считаете его полезным. - person Paulo E. Cardoso; 28.02.2014