지난번 포스팅까지는 R 지리공간 벡터 데이터 (geometry vector objects) 에 대한 속성정보 가져오기 (rfriend.tistory.com/622), 그룹별 집계하기 (rfriend.tistory.com/624), 두 개의 테이블 간 Join 하기 (rfriend.tistory.com/625), Key 값에 대한 문자열 매핑을 테이블 Join 하기 (rfriend.tistory.com/626), 새로운 속성정보 만들기와 지리정보 제거하기 (rfriend.tistory.com/627)에 대해서 소개하였습니다.

 

이번 포스팅부터는 레스터 객체 데이터셋을 조작하는 방법(manipulating raster objects dataset)을 몇 개의 포스팅으로 나누어서 소개하겠습니다.

 

그 중에서도 이번 포스팅에서는 R 문자형을 요인형으로 변환하여 레스터 객체 데이터의 속성으로 만드는 방법(making raster objects attributes by converting character to factor type)을 알아보겠습니다.

 

 

R raster objects' attritubes with numeric, integer, logical and factor types. No support for character.

 

 

 

 

R의 레스터 객체(raster objects)는 데이터 속성으로 숫자형(numeric), 정수형(integer), 논리형(logical), 요인형(factor) 데이터 유형을 지원하며, 문자형(character)은 지원하지 않습니다. 따라서 문자형으로 이루어진 범주형 변수 값(categorical variables' values)을 가지고 레스터 객체의 속성(attritubes)을 만들고 싶으면 (1) 먼저 문자형을 요인형으로 변환 (또는 논리형으로 변환)하고, --> (2) 요인형 값을 속성 값으로 해서 레스터 객체를 만들어야 합니다.

 

 

먼저, 레스터 객체 데이터에 대한 이해를 돕기위해, 정수형(integer) 값을 속성 값으로 가지는 레스터 객체를 raster 패키지의 raster() 함수를 사용해서 만들어보겠습니다. 아래의 예에서는 6 x 6 = 36개의 픽셀(pixels, cells)에,  x와 y의 좌표값의 최소~최대값 범위의 좌표에, 1~36까지의 정수를 속성 값으로 가지는 레스터 객체 데이터 입니다.

 

R 레스터 객체 데이터(Raster object in R)에 대한 보다 자세한 소개는 rfriend.tistory.com/589rfriend.tistory.com/605 를 참고하세요.

 

## ========================================================
## R GeoSpatial data analysis
## : Manipulating Raster Objects
## [reference] https://geocompr.robinlovelace.net/attr.html
## ========================================================

## raster data represent continuous surfaces. 
## Because of their unique structure, 
## subsetting and other operations on raster datasets work in a different way. 

library(raster)

## -- creating an example raster dataset
elev <- raster(nrows = 6, # integer > 0. Number of rows
               ncols = 6, # integer > 0. Number of columns
               #res = 0.5, # numeric vector of length 1 or 2 to set the resolution
               xmn = -1.5, # minimum x coordinate (left border)
               xmx = 1.5,  # maximum x coordinate (right border)
               ymn = -1.5, # minimum y coordinate (bottom border)
               ymx = 1.5,  # maximum y coordinate (top border)
               vals = 1:36) # values for the new RasterLayer

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)


plot(elev, main = 'raster datasets with numeric valeus')

 

 

이제 본론으로 넘어가서, 문자형으로 이루어진 범주형 변수를 요인형으로 변환한 후에, 이를 다시 레스터 객체의 속성으로 하여 레스터 객체를 만드는 방법을 소개하겠습니다.

 

 

(1)

 

문자형(character)을 요인형(factor)으로 변환할 때는 R base 패키지의 factor() 를 사용합니다. 이때 요인의 수준(levels)은 범주형 변수 내 유일한(unique) 문자열을 오름차순으로 정렬(sorting in an increasing order)하여 부여가 되는데요, 만약 요인의 수준(levels)을 특정 순서에 맞게 분석가가 수작업으로 설정을 하고 싶다면 levels 매개변수를 사용해서 직접 요인 수준을 입력을 해주면 됩니다.

 

아래 예에서는 모래의 굵기의 수준에 따라서 "점토(clay)", "미세모래(silt)", "모래(sand)"의 순서로 levels 매개변수를 이용해 요인의 수준을 설정해서, factor() 함수로 문자형으로 구성된 범주형 변수('grain_order')를 요인형 변수('grain_fact')으로 변환해준 것입니다. 

<--> 만약 factor() 함수로 요인형으로 변환할 때 levels 매개변수로 요인 수준의 순서를 지정해주지 않는다면, default 인 유일한 문자형 값들의 오름차순 정렬에 따라서 ["clay", "sand", "silt"] 의 순서로 설정이 되었을 것입니다.

 

## -- raster objects can contain values of class numeric, integer, logical or factor, 
## but not character.
## Raster objects can also contain categorical values of 
## class logical or factor variables in R.


grain_order <- c("clay", "silt", "sand")

## random sampling with replacement
set.seed(1004)
grain_char <- sample(grain_order, 36, replace = TRUE)
grain_char
# [1] "sand" "silt" "clay" "clay" "clay" "sand" "silt" "silt" "silt" "clay" "sand" "silt" "sand" "sand"
# [15] "sand" "clay" "sand" "clay" "sand" "clay" "sand" "sand" "silt" "clay" "sand" "silt" "sand" "clay"
# [29] "clay" "clay" "sand" "sand" "clay" "sand" "sand" "clay"


## converting character into factor
grain_fact <- factor(grain_char, 
                     # ordered factor: clay < silt < sand in terms of grain size.
                     levels = grain_order) 

grain_fact
# [1] sand silt clay clay clay sand silt silt silt clay sand silt sand sand sand clay sand clay sand clay
# [21] sand sand silt clay sand silt sand clay clay clay sand sand clay sand sand clay
# Levels: clay silt sand

 

 

 

(2) 요인형 값을 속성으로 한 레스터 객체 데이터 만들기 (creating raster objects with factor values)

 

위의 (1)번에서 문자열 값을 요인형으로 변환한 값을 가지고 raster 패키지의 raster() 함수를 사용해서 레스터 객체를 만들어보겠습니다.  행의 수(nrows) 6개, 열의 수(ncols) 6개의 총 36개 픽셀(pixcels, cells)을 가지는 레스터 객체에 raster(nrows = 6, ncols = 6, res = 0.5, vals = grain_fact)('grain_fact' 는 요인형 값을 가지는 벡터임) 을 입력하였습니다.

 

레스터 객체 데이터에 대해서 plot() 함수로 간단하게 시각화를 할 수 있습니다. 이때 요인형의 수준 값(levels)인 clay = 1, silt = 2, sand = 3 의 정수값을 가지고 시각화를 하게 됩니다.

 

## -- creating a raster dataset with factor variable in R
grain_raster <- raster(nrows = 6, ncols = 6, 
                       #res = 0.5, 
                       xmn = -1.5, xmx = 1.5, ymn = -1.5, ymx = 1.5, 
                       vals = grain_fact)

grain_raster
# 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


plot(grain_raster, main = 'raster dataset with factor(categorical) values')

 

 

이번에는 levels() 와 cbind() 함수를 사용해서 기존의 요인의 수준에다가 wetness = c("wet", "moist", "dry") 라는 새로운 요인 수준을 추가(adding new factor levels to the attritube table) 하여 보겠습니다. 

 

## -- Use the function levels() for retrieving and 
##    adding new factor levels to the attribute table:
levels(grain_raster)
# [[1]]
# ID VALUE
# 1  1  clay
# 2  2  silt
# 3  3  sand

## adding new factor levels
levels(grain_raster)[[1]] = cbind(levels(grain_raster)[[1]], 
                                  wetness = c("wet", "moist", "dry"))


## retrieving factor levels
levels(grain_raster)
# [[1]]
# ID VALUE wetness
# 1  1  clay     wet
# 2  2  silt   moist
# 3  3  sand     dry

 

 

레스터 객체 데이터의 "attritubes"라는 이름의 속성 테이블(attritube table)에 요인형 수준 값이 저장되어 있으며, 여기에 새로운 요인형 수준 값이 추가되는 것입니다.  ratify() 함수를 사용하면 이 속성 테이블(attritube table)에 저장되어 있는 값을 조회할 수 있습니다.

 

## -- The raster object stores the corresponding look-up table 
## or “Raster Attribute Table” (RAT) as a data frame in a new slot named attributes, 
## which can be viewed with ratify(grain)

ratify(grain_raster)
# 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
# 1
# 2
# 3

 

 

레스터 객체의 각 픽셀(pixcel, cell)은 단 하나의 값만을 가질 수 있습니다. 이 예제에서는 각 픽셀이 하나의 요인 수준 값을 가지고 있는데요, 아래 예는 레스터 객체의 1번, 10번, 26번 픽셀의 요인 수준 값이 3, 1, 2 이고, 이들 요인 수준 값에 대응하는 속성 정보를 factorValues() 함수를 사용하여 속성 테이블(attritube table) 로 부터 매핑하여 보여주는 것입니다.

 

## -- looking up the attributes in the corresponding attribute table
grain_raster[c(1, 10, 26)]
# [1] 3 1 2

factorValues(grain_raster, grain_raster[c(1, 10, 26)])
# VALUE wetness
# 1  sand     dry
# 2  clay     wet
# 3  silt   moist

 

[Reference]

* Geo-Computation with R
  - 'Attribute data operations': geocompr.robinlovelace.net/attr.html

 

 

다음번 포스팅에서는 지리공간 레스터 데이터 가져오는 방법(Raster subsetting, rfriend.tistory.com/629) 에 대하여 소개하겠습니다.

 

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

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

 

 

반응형
Posted by Rfriend

댓글을 달아 주세요

  1. jjangmo91 2022.04.21 23:06 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 선생님 블로그를 보며 많이 배우고 있는 학생입니다.

    저는 여러 래스터 파일들의 다중공선성을 확인하고 상관계수가 높은 변수들을 제거하고 싶은데요.

    에러: 크기가 61.8GB인 벡터를 할당할 수 없습니다. 라고 메세지가 떠서 메모리 제한도 늘렸는데도 진행이 불가능해서.. 혹시 다른 방법이 있을까 답답한 마음에 죄송하게도 질문 글을 올립니다.

    코드는 아래와 같습니다.

    ### packages ###
    library(tidyverse)
    library(ggplot2)
    library(raster)
    library(dismo)
    library(rgdal)
    library(usdm)
    library(corrplot)

    ###--------------------------------------------------------------------------------------------------------------------------------------------------

    ### directory ###
    path <- "D:/GIS/04Bioclim/historical"

    ### file list ###
    bioclim <- list.files(path, pattern = ".tif$", full.names = T)

    ### raster stack ###
    stack_bioclim = stack(bioclim)
    plot(stack_bioclim)

    ### set CRS for raster objects ###
    crs_rgdal = rgdal::make_EPSG()
    crs_rgdal[crs_rgdal$code == 5186,]
    projection(stack_bioclim) = "+proj=tmerc +lat_0=38 +lon_0=127 +k=1 +x_0=200000 +y_0=600000 +ellps=GRS80 +units=m +no_defs"

    ### memory limit ###
    memory.limit(size=9999999999999)

    ### Correlation ###
    pairs(stack_bioclim)
    v2 <- vifcor(stack_bioclim, th = 0.7)