Сгущать значения растра в зависимости от атрибута класса

#r #raster

#r #растр

Вопрос:

У меня есть значения растра (пакет растров):

 values(r)<-c(2,1,0,0,1,
             1,1,1,0,0,
             1,0,1,0,0,
             2,1,0,1,0,
             2,2,0,0,2)
 

и я хотел бы найти clumps = patches в каждом классе (значения 1,2). К сожалению, функция clump (Raster) возвращает исправления, разделенные значением O или NA, поэтому она смешивает значения 1,2 в один патч.

Кроме того, я хотел бы исключить исправления, содержащие только 1 пиксель, и сделать их NA, что возможно с помощью

 values(rc)[!duplicated(values(rc)) amp; !duplicated(values(rc),fromLast=T)] <- NA
#(many thanks to @agstudy)
 

Однако я хотел бы исключить участки, содержащие только 1 пиксель, но разделенные значением класса (1,2).

Наконец, я хотел бы получить:

 values(r)<-c(NA,1,NA,NA,NA,
             1,1,1,NA,NA,
             1,NA,1,NA,NA,
             2,NA,NA,1,NA,
             2,2,NA,NA,NA)
 

Пример кода:

 library("raster")
r <- raster(ncols=5, nrows=5)
values(r)<-c(2,1,0,0,1,
             1,1,1,0,0,
             1,0,1,0,0,
             2,1,0,1,0,
             2,2,0,0,2)
 

Ответ №1:

Возможно, слишком поздно, но я обнаружил, что этот вопрос остался без ответа во время работы над той же темой.

Ответ заключается в переборе всех значений класса и выполнении сгущения для каждого класса отдельно при заполнении нового растра NA, где сгустки имеют частоту 1 (исходный код для удаления небольших сгустков: https://geoscripting-wur.github.io/AdvancedRasterAnalysis/#Applying_a_raster_sieve_by_clumping ). При умножении этого NA-растра на оригинал удаляются участки размером в 1 пиксель.

Обратите внимание, что мы должны развернуть растр, иначе левый и правый края «соприкасаются», поскольку координаты x по умолчанию от -180 до 180. В конце конечный растр обрезается до исходного экстента.

 # extend raster, otherwise left and right edges are 'touching'
r <- extend(r, c(1,1))

# get al unique class values in the raster
clVal <- unique(r)

# remove '0' (background)
clVal <- clVal[!clVal==0]

# create a 1-value raster, to be filled in with NA's
r.NA <- setValues(raster(r), 1)

  # set background values to NA
  r.NA[r==0]<- NA

# loop over all unique class values
for (i in clVal) {

  # create amp; fill in class raster
  r.class <- setValues(raster(r), NA)
  r.class[r == i]<- 1

  # clump class raster
  clp <- clump(r.class)

  # calculate frequency of each clump/patch
  cl.freq <- as.data.frame(freq(clp))

  # store clump ID's with frequency 1
  rmID <- cl.freq$value[which(cl.freq$count == 1)]

  # assign NA to all clumps whose ID's have frequency 1
  r.NA[clp %in% rmID] <- NA
} 

# multiply original raster by the NA raster
r <- r * r.NA

# crop the originally extended raster ((row 2-6 and column 2-6))
r <- crop(r, extent(r, 2, 6, 2, 6 ))

getValues(r)
#  [1] NA  1 NA NA NA
#       1  1  1 NA NA  
#       1 NA  1 NA NA  
#       2  1 NA  1 NA  
#       2  2 NA NA NA