'subsetting layers from multi-layers raster objects'에 해당되는 글 1건

  1. 2021.03.07 [R 지리공간 데이터 분석] 지리 레스터 객체 데이터 일부 가져오기 (Raster subsetting)

지난번 포스팅에서는 지리공간 레스터 객체 데이터를 시작하면서, 문자형을 값으로 가지는 범주형 변수를 요인형으로 변환하여 --> 요인형 변수를 속성정보로 하여 레스터 객체를 만드는 방법을 소개하였습니다. (rfriend.tistory.com/628

 

이번 포스팅에서는 레스터 객체 데이터의 일부를 가져오는 방법(Raster subsetting)을 소개하겠습니다.

 

(1) 레스터 객체의 각 픽셀(pixcels, cells) 중 일부 행(rows), 열(column) 가져오기

    (subsetting rows, columns from laster objects) 

(2) 다층 레스터 객체(multi-layered laster objects)로 부터 일부 층(layers) 가져오기

    (subsetting layers from multi-layered laster objects, a raster brick or stack)

(3) 레스터 객체의 일부 값을 수정하기 (modifying values in raster objects)

 

 

 

 

레스터 객체의 일부분 가져오기(Raster subsetting)는 Base R 의 '[' 연산자와 raster 패키지의 raster::subset() 함수를 사용해서 할 수 있습니다. 먼저 Base R의 '[' 연산자를 사용한 일부분 가져오기를 살펴보겠습니다. 

 

 

(1) 레스터 객체의 각 픽셀(pixcels, cells) 중 일부 행(rows), 열(column) 가져오기

    (subsetting rows, columns from laster objects)

 

예제로 사용하기 위해, 6개의 행과 6개의 열의 총 36개 픽셀로 구성되어 있고 1~36의 정수를 속성 값으로 가지는 레스터 객체를 만들어보겠습니다. 

 

## ========================================================
## R Raster subsetting
## - reference: https://geocompr.robinlovelace.net/attr.html
## ========================================================

library(raster)

## sample raster object
elev <- raster(nrows = 6, ncols = 6, 
              xmn = -1.5, xmx = 1.5, ymn = -1.5, ymx = 1.5, 
              vals = 1:36)

elev
# class      : RasterLayer 
# dimensions : 6, 6, 36  (nrow, ncol, ncell)
# resolution : 0.5, 0.5  (x, y)
# extent     : -1.5, 1.5, -1.5, 1.5  (xmin, xmax, ymin, ymax)
# crs        : +proj=longlat +datum=WGS84 +no_defs 
# source     : memory
# names      : layer 
# values     : 1, 36  (min, max)

 

 

레스터 객체의 행과 열의 일부분을 가져오는 것은 Base R의 '[' 연산자('[' operator) 를 사용합니다. raster_object[i, j] 또는 raster_object[Cell_IDs] 구문으로 i행과 j 열을 가져올 수 있습니다.  레스터 객체로 부터 일부분 가져오기는 '(a) 지리정보가 아닌 속성 정보를 가져오기(non-spatial subsetting)'와, '(b) 지리정보 가져오기 (spatial subsetting)' 의 두가지 유형으로 나눌 수 있는데요, 이번 포스팅은 '(a) 레스터 객체로부터 지리정보가 아닌 속성 정보를 가져오기'에 대해서만 다루겠습니다. 

 

elev[1, 1] 은 evel 레스터 객체로 부터 1행과 1열에 위치한 픽셀(pixel, cell) 에 위치한 속성 값을 가져온 것입니다. 

elev[1] 은 Cell ID 1번에 위치한 속성 값을 가져온 것입니다. (R 레스터는 좌측 상단에서 부터 1행 1열, Cell ID 1번이 시작하므로 elev[1, 1] 과 elev[1] 은 동일한 위치의 픽셀 속성 값을 가져옴)

 

## -- (1) Raster subsetting is done with the base R operator '['
## , which accepts a variety of inputs:
## - non-spatial subsetting: row-column indexing, cell IDs
## - spatial subsetting: coordinates, another spatial object

## subsetting the value of the top left pixel in the raster object 'elev'
## (1-1) row-column indexing
elev[1, 1]
# [1] 1

## (1-2) cell IDs
elev[1]
# [1] 1

 

 

레스터 객체의 전체 속성 값을 Cell ID의 순서대로 모두 가져오고 싶으면 values(), getValues() 함수 또는 [] 연산자를 사용하면 됩니다. 

 

## -- extracting all values or compelte rows
## (a) values()
values(elev)
# [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# [26] 26 27 28 29 30 31 32 33 34 35 36


## or, eqivalently
# (b) getValues()
getValues(elev) 

# (c) []
elev[]

 

 

 

(2) 다층 레스터 객체(multi-layered laster objects)로 부터 일부 층(layers) 가져오기

    (subsetting layers from multi-layered laster objects, a raster brick or stack)

 

다층 레스터 객체(multi-layered laster objects)로는 RasterBrick 클래스와 RasterStack 클래스가 있습니다. (자세한 설명은 rfriend.tistory.com/617 를 참고하세요.)  이들 다층 레스터 객체로 부터 특정 층을 가져오려면 raster 패키지의 subset() 함수를 사용합니다. 

 

먼저, 예제로 사용할 수 있도록 grain 이라는 레스터 객체를 하나 더 만들고, 이를 (1)에서 만들었던 elev 레스터 객체에 stack() 함수로 쌓아서 다층 레스터 객체를 만들어보겠습니다

 

## -- for multi-layered raster objects 'stack' or 'brick', 
## values(), getValues() returns the cell value(s) for each layer. 
## 3 raster classes: https://rfriend.tistory.com/617

grain_order <- c("clay", "silt", "sand")
grain_char <- sample(grain_order, 36, replace = TRUE)
grain_fact <- factor(grain_char, levels = grain_order)
grain <- raster(nrows = 6, ncols = 6, res = 0.5, 
                xmn = -1.5, xmx = 1.5, ymn = -1.5, ymx = 1.5,
                vals = grain_fact)

grain
# class      : RasterLayer 
# dimensions : 6, 6, 36  (nrow, ncol, ncell)
# resolution : 0.5, 0.5  (x, y)
# extent     : -1.5, 1.5, -1.5, 1.5  (xmin, xmax, ymin, ymax)
# crs        : +proj=longlat +datum=WGS84 +no_defs 
# source     : memory
# names      : layer 
# values     : 1, 3  (min, max)
# attributes :
#   ID VALUE
# 1  clay
# 2  silt
# 3  sand


## making a RaserStack class object using stack() function
r_stack <- stack(elev, grain)
names(r_stack) <- c("elev", "grain")

r_stack
# class      : RasterStack 
# dimensions : 6, 6, 36, 2  (nrow, ncol, ncell, nlayers)
# resolution : 0.5, 0.5  (x, y)
# extent     : -1.5, 1.5, -1.5, 1.5  (xmin, xmax, ymin, ymax)
# crs        : +proj=longlat +datum=WGS84 +no_defs 
# names      : elev, grain 
# min values :    1,     1 
# max values :   36,     3

 

 

values() 로 r_stack 안의 각 층별 속성값을 조회해보면 아래처럼 "elev" 층과 "grain" 층의 각 Cell 별로 들어있는 속성 값이 들어있음을 알 수 있습니다. (values(r_stack), getValues(r_stack), r_stack[] 모두 동일하게 각 층의 모든 속성값을 반환합니다.) 

 

values(r_stack)
#getValues(r_stack)  # or equivalently
#r_stack[]           # or equivalently

# elev grain
# [1,]    1     3
# [2,]    2     3
# [3,]    3     1
# [4,]    4     3
# [5,]    5     3
# [6,]    6     1
# [7,]    7     1
# [8,]    8     3
# [9,]    9     1
# [10,]   10     1
# [11,]   11     2
# [12,]   12     3
# [13,]   13     2
# [14,]   14     2
# [15,]   15     1
# [16,]   16     3
# [17,]   17     1
# [18,]   18     1
# [19,]   19     2
# [20,]   20     3
# [21,]   21     1
# [22,]   22     3
# [23,]   23     1
# [24,]   24     2
# [25,]   25     1
# [26,]   26     2
# [27,]   27     3
# [28,]   28     2
# [29,]   29     3
# [30,]   30     1
# [31,]   31     1
# [32,]   32     3
# [33,]   33     1
# [34,]   34     2
# [35,]   35     1
# [36,]   36     1

 

 

다층 레스터 객체에서 특정 층을 가져오려면 raster::subset(raster_object, "layer_name") 구문을 사용할 수 있습니다.  아래 예에서는 r_stack 다층 레스터 객체에서 "elev" 층(layer)을 가져온 것입니다. 

 

## (2-1) raster::subset()
raster::subset(r_stack, "elev")
# class      : RasterLayer 
# dimensions : 6, 6, 36  (nrow, ncol, ncell)
# resolution : 0.5, 0.5  (x, y)
# extent     : -1.5, 1.5, -1.5, 1.5  (xmin, xmax, ymin, ymax)
# crs        : +proj=longlat +datum=WGS84 +no_defs 
# source     : memory
# names      : elev 
# values     : 1, 36  (min, max)


## (2-2) '[[' operator
r_stack[["elev"]]


## (2-3) '$' operator
r_stack$elev

 

 

 

(3) 레스터 객체의 일부 값을 수정하기 (modifying values in raster objects)

 

만약 레스터 객체의 일부 값을 새로운 값으로 덮어쓰기, 업데이트, 수정을 하고 싶으면 앞에서 소개한 subsetting 기능을 활용해서 원하는 위치의 행과 열, 픽셀 ID(Pixel ID, Cell ID) 또는 층(layer) 의 subsetting 한 부분에 새로운 속성 값을 할당(<-, =) 하면 됩니다. 

 

아래의 첫번째 예는 elev[1, 1]  <- 0 은 elev 레스터 객체의 1행 1열 위치의 셀에 새로운 값 '0'을 할당한 것입니다.  

아래의 두번째 예는 evel[1, 1:3] <- 0 은 elev 레스터 객체의 1행의 1~3열 위치 셀에 새로운 값 '0'을 할당하여 속성값을 수정한 것입니다. 

 

## -- (3) modifying the existing values by overwriting 
##        with a subsetting operation
elev[1, 1] <- 0

elev[]
# [1]  0  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# [26] 26 27 28 29 30 31 32 33 34 35 36


## multiple cells can be modified with a subsetting operation. 
elev[1, 1:3] <- 0
values(elev)
# [1]  0  0  0  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# [26] 26 27 28 29 30 31 32 33 34 35 36

 

 

[Reference]

* Geo-computation with R

  - 'Attribute data operations': geocompr.robinlovelace.net/attr.html

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다.

행복한 데이터 과학자 되세요!  :-)

 

728x90
반응형
Posted by Rfriend
,