Вычисление площади из больших пространственных пикселей DataFrame

У меня есть объект с именем cr1, который представляет собой большой SpatialPixelsDataFrame озера. Вот ссылка на файл: https://www.dropbox.com/s/uuvlmxmri144hp2/macrosmall.rdata?dl=0

Я думаю, что каждый пиксель имеет размер ячейки 1 м x 1 м, однако я думаю, что этот атрибут нигде не указан. «макро» — измеренная высота подводных макрофитов в озере. Структура выглядит так.

    Formal class 'SpatialPixelsDataFrame' [package "sp"] with 7 slots

  ..@ data       :'data.frame': 252234 obs. of  1 variable:
  .. ..$ macro: num [1:252234] 0.0468 0.0518 0.0445 0.046 0.0477 ...

  ..@ coords.nrs : num(0) 

  ..@ grid       :Formal class 'GridTopology' [package "sp"] with 3 slots

  .. .. ..@ cellcentre.offset: Named num [1:2] 3404494 5872334

  .. .. .. ..- attr(*, "names")= chr [1:2] "x" "y"
  .. .. ..@ cellsize         : Named num [1:2] 1 1

  .. .. .. ..- attr(*, "names")= chr [1:2] "x" "y"
  .. .. ..@ cells.dim        : Named int [1:2] 776 536

  .. .. .. ..- attr(*, "names")= chr [1:2] "x" "y"
  ..@ grid.index : int [1:252234] 415333 415334 415335 415336 415337 415338 
415339 414554 414555 414556 ...

  ..@ coords     : num [1:252234, 1:2] 3404666 3404667 3404668 3404669 3404670 ...
  .. ..- attr(*, "dimnames")=List of 2

  .. .. ..$ : chr [1:252234] "949" "950" "951" "952" ...

  .. .. ..$ : chr [1:2] "x" "y"

  ..@ bbox       : num [1:2, 1:2] 3404493 5872333 3405269 5872869

  .. ..- attr(*, "dimnames")=List of 2

  .. .. ..$ : chr [1:2] "x" "y"

  .. .. ..$ : chr [1:2] "min" "max"

  ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot

  .. .. ..@ projargs: chr NA

Я хотел бы рассчитать площадь, покрываемую для определенных интервалов высоты макрофитов (т.е. площадь, покрываемую для интервалов «макро»).

Как я могу указать разрешение или размер каждой ячейки (= 1 м x 1 м)? Какой пакет и функция обрабатывает оценку площади SpatialPixelsDataFrame?

Я пока только карту загрузил

library(sp)
library(raster)

load("macrosmall.rdata")

и попробовал пару вещей:

area(cr1)

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

intervals <- list(c(0.1,0.2), 
              c(0.2,0.3),
              c(0.3,0.4))

sapply(intervals, function(x) { 
  sum(cr1[] > x[1] & cr1s[] <= x[2])
})

Но в основном я всегда получаю одни и те же предупреждающие сообщения.

Предупреждающее сообщение: В .local(x, ...): эта функция полезна только для растровых* объектов с координатами долготы/широты.

Обратите внимание, что рассматриваемая территория довольно маленькая (25 га).

Может ли кто-нибудь подтолкнуть меня в правильном направлении?


person Itsa Me    schedule 28.04.2018    source источник
comment
Размерность 776 и 536, так что 776 * 536 = 415936 m^2?   -  person www    schedule 28.04.2018
comment
это может быть для всей прямоугольной области карты. Однако озеро не прямоугольное и не заполняет все пиксели.   -  person Itsa Me    schedule 28.04.2018
comment
Судя по предоставленному вами коду, например area(r), вам нужна вся область. Поскольку вы не предоставили воспроизводимый пример вашего набора данных, нет возможности дать подробный ответ.   -  person www    schedule 28.04.2018
comment
Я отредактировал исходные вопросы и добавил интервалы макропеременной, для которой я хочу оценить площадь.   -  person Itsa Me    schedule 28.04.2018
comment
Пожалуйста, поделитесь воспроизводимым примером ваших данных   -  person www    schedule 28.04.2018
comment


Ответы (2)


Я действительно смущен. Вы сказали, что работаете над spatialPixelsDataFrame, но предоставленные вами данные, cr1, являются растровым объектом.

Во всяком случае, здесь я показал возможное решение для вычисления площади.

library(sp)
library(raster)

# Load the RData
load("macrosmall.RData")

# View the raster layer
cr1
# class       : RasterLayer 
# dimensions  : 200, 269, 53800  (nrow, ncol, ncell)
# resolution  : 1, 1  (x, y)
# extent      : 3405000, 3405269, 5872500, 5872700  (xmin, xmax, ymin, ymax)
# coord. ref. : NA 
# data source : in memory
# names       : macro 
# values      : 0, 1.896009  (min, max)

# Plot the raster layer
plot(cr1)

введите здесь описание изображения

Я не уверен, какие растровые значения указывают на «озеро». Предполагая, что все клетки, не относящиеся к NA, являются озером, мы можем сделать следующее.

# Get all cell values
cells <- values(cr1)

# Remove NA
cells_nonNA <- cells[!is.na(cells)]

# Count how many cells
length(cells_nonNA)
# [1] 36143

Так как 1 клетка равна 1 м^2, общая площадь озера равна 36143 м^2.

Предполагая, что значения растра для озера выше 1, мы снова можем подмножить значения ячеек.

cells_above1 <- cells_nonNA[cells_nonNA > 1]
length(cells_above1)
# [1] 77
person www    schedule 28.04.2018
comment
Извините, мне нужен был быстрый способ обрезать данные, так как я торопился. Цель состоит в том, чтобы вычислить площадь макрофитов. Они должны иметь определенные интервалы высоты. Значения макрофитов варьируются от 0,00 м до 1,89 м. Я хочу, например. рассчитать площадь для макрофитов высотой от 0,1 м до 0,3 м, от 0,3 м до 0,6 м, от 0,6 м до 1,0 м и т. д. Мне все равно, в каком формате данных это происходит, растр и spdf, кажется, в порядке. Похоже, что значение макроса, которое присутствовало в spdf, теперь является значением, отображаемым в растровых данных. Затем ваш последний шаг может быть применен к желаемым интервалам. Спасибо! - person Itsa Me; 28.04.2018

Вы должны предоставить простые примеры данных, сгенерированные кодом, а не файл. Например

library(raster)
r <- raster(nrow=20, ncol=26, ext=extent(3405000, 3405269, 5872500, 5872700))
values(r) <- 1:ncell(r) / 280
set.seed(-1)
r[sample(ncell(r), 100)] <- 0

Решение состоит в том, чтобы сначала создать интересующие вас классы. Вы можете использовать cut или reclassify. Здесь с reclassify:

m <- matrix(c(0, 0.1, 1,
              0.1, 0.5, 2,
              0.5, 1, 3,
              1, 2, 4), ncol=3, byrow=TRUE)

rc <- reclassify(r, m)

А затем посчитайте количество ячеек в каждом классе:

f <- freq(rc)

Пока ваш CRS не является долготой/широтой, вы можете умножить количество ячеек на площадь ячейки, чтобы получить площадь (но в вашем случае площадь равна 1, поэтому в этом нет необходимости).

f <- data.frame(f)
f$area <- f$count * prod(res(rc))

Если данные находятся на lon/lat, вам нужно будет сделать

a <- area(rc)
ff <- zonal(a, rc, "sum") 
person Robert Hijmans    schedule 28.04.2018
comment
я бы сделал это, если бы я знал, как в первую очередь. я мог получить структуру данных (или параметры для определенных значений), отличную от той, что была у меня, так что это могло привести к большей путанице, чем необходимо. - person Itsa Me; 30.04.2018