Modul ini disusun dengan merujuk pada beberapa referensi yang tertulis di bagian akhir dari modul ini. Secara umum, modul ini akan memberikan beberapa ilustrasi terkait dengan topik berikut:
Perbedaan utama antara data spasial dan bukan spasial, adalah adanya atribut lokasi yang melekat pada data. Informasi tersebut dapat berupa informasi titik lokasi maupun area. Menurut Cressie & Moores (2021), suatu pemodelan proses spasial dibedakan menjadi tiga, yaitu:
Sedangkan, berdasarkan penyimpanannya, data spasial (lebih spesifiknya, data GIS) secara umum dibedakan menjadi dua jenis, yaitu:
Â
Data titik menyimpan informasi lokasi menurut coordinate reference system (CRS), data garis merupakan beberapa titik yang dihubungkan oleh garis sehingga membentuk informasi jarak/panjang, sedangkan data poligon berupa suatu bidang yang memiliki luasan area. Data poligon seringkali merepresentasikan suatu peubah yang bersifat diskret.
Â
Â
Secara umum, terdapat dua paket utama pada lingkungan R yang dapat
digunakan pada data spasial, yaitu paket sp
dan
sf
. Paket sp
dikembangkan lebih dulu, sekitar
tahun 2005, sedangkan paket sf
dikembangkan sekitar tahun
2016. Oleh karenanya, paket sf
dianggap lebih compatible
dengan lingkungan tidymodels
.
Paket sf
konon memang dirancang untuk menggantikan
sp
, namun hingga saat ini masih cukup banyak metode
pemodelan dan analisis yang bergantung pada paket sp
. Oleh
karenanya, beberapa sumber menyarankan agar kita tetap mempelajari
keduanya, dan mungkin perlu membiasakan untuk mengonversi objek
sf
menjadi sp
atau sebaliknya.
Paket lainnya yang akan digunakan adalah raster
, untuk
menangani data jenis raster/grid. Serupa dengan kondisi sebelumnya,
terdapat paket lain yaitu terra
yang memiliki fitur yang
mirip dengan raster
namun dianggap memiliki lebih banyak
pengembangan dan pembaruan.
Selain dari paket yang telah disebutkan di atas, terdapat beberapa paket lain yang cukup banyak digunakan untuk memproses data spasial, masing-masing spesifik dengan kebutuhan analisis yang akan dilakukan. Untuk lebih lengkapnya, kita dapat melihatnya pada laman CRAN Task View: Analysis of Spatial Data, pada link berikut: https://cran.r-project.org/web/views/Spatial.html.
Membaca data spasial berjenis vektor dapat dilakukan menggunakan
fungsi st_read()
. Silahkan mengunduh data yang digunakan
pada ilustrasi ini pada link berikut: klik
disini
Data spasial dapat disimpan dalam beberapa format, seperti shp, json,
tiff, dll. Namun jenis shp (shapefiles) termasuk yang paling banyak
digunakan. Data dengan format shapefile akan memerlukan beberapa file
dengan nama yang sama, di antaranya adalah file dengan format .shp,
.shx, .dbf, .prj, dsb. Sehingga kita perlu menyimpan seluruh file
tersebut dalam satu folder. Folder tersebut selanjutnya disebut sebagai
dsn
, sedangkan nama file disebut sebagai
layer
. Selanjutnya, impor data dapat dilakukan dengan
fungsi seperti bawah ini.
<nama object> <-st_read(dsn="<nama folder>", layer="<nama file>")
Berikut contohnya:
library(sf)
## Linking to GEOS 3.11.2, GDAL 3.7.2, PROJ 9.3.0; sf_use_s2() is TRUE
veg<-st_read(dsn="cape_peninsula/veg", layer="Vegetation_Indigenous")
## Reading layer `Vegetation_Indigenous' from data source
## `D:\Dept.STK\Courses\Statistika Spasial (S2)\STA 1553 TA 23-24, genap\P1\cape_peninsula\veg'
## using driver `ESRI Shapefile'
## Simple feature collection with 1325 features and 5 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -63972.95 ymin: -3803535 xmax: 430.8125 ymax: -3705149
## Projected CRS: WGS_1984_Transverse_Mercator
Selanjutnya kita dapat mengidentifikasi CRS yang digunakan pada data
tersebut dengan fungsi st_crs()
.
st_crs(veg)
## Coordinate Reference System:
## User input: WGS_1984_Transverse_Mercator
## wkt:
## PROJCRS["WGS_1984_Transverse_Mercator",
## BASEGEOGCRS["WGS 84",
## DATUM["Hartebeesthoek94",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6148]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["Degree",0.0174532925199433]]],
## CONVERSION["unnamed",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["Degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",19,
## ANGLEUNIT["Degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",1,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]]]
Secara umum, terdapat tiga komponen utama dari informasi CRS di atas, yaitu:
BASEGEOGCRS
, informasi CRS geografis
(unprojected)
CONVERSION
, informasi proyeksi, keluaran di atas
memperlihatkan bahwa proyeksi menggunakan Tranverse Mercator Lo19
("Longitude of natural origin",19
), yang artinya bahwa data
berpusat pada 19 derajat pada garis bujur.
CS
, sumbu kartesius yang digunakan. Pada keluaran di
atas, terlihat bahwa digunakan sumbu dengan arah utara dan timur dengan
satuan meter.
Selanjutnya, kita juga dapat memerika kelas dari objek
veg
tersebut.
class(veg)
## [1] "sf" "data.frame"
Karena objek tersebut mengandung dua kelas, maka kita dapat menerapkan fungsi yang compatible untuk keduanya pada objek tersebut.
head(veg)
Kolom geometry
mengimpan informasi terkait dengan ukuran
geometri pada suatu objek sf
, contohnya titik, garis,
poligon, yang bersesuaian dengan baris pada atribut data pada
kolom-kolom yang berada di depannya.
Seandainya kita perlu menyimpan suatu objek sf
ke dalam
sebuah file, maka kita dapat menggunakan fungsi st_write()
,
seperti pada contoh berikut ini.
st_write(veg, "cape_peninsula/veg/Vegetation_Indigenous_duplicate.shp", append=F)
## Deleting layer `Vegetation_Indigenous_duplicate' using driver `ESRI Shapefile'
## Writing layer `Vegetation_Indigenous_duplicate' to data source
## `cape_peninsula/veg/Vegetation_Indigenous_duplicate.shp' using driver `ESRI Shapefile'
## Writing 1325 features with 5 fields and geometry type Polygon.
Jika kita ingin menimpa file dengan nama yang sama (jika sudah pernah
disimpan), maka kita perlu mengganti argumen
append=TRUE
.
Cara paling mudah untuk menghasilkan visualisasi adalah dengan fungsi
plot()
seperti pada contoh berikut ini.
plot(veg)
Terlihat pada keluaran di atas bahwa terdapat 5 plot yang dihasilkan.
Hal ini karena objek sf
secara default akan menghasilkan
plot untuk setiap kolom atribut pada data. Jadi, kita perlu memilih
salah satu atribut, sesuai dengan kebutuhan, untuk diplotkan.
plot(veg[3])
Kita dapat pula membuat visualisasi menggunakan ggplot
,
seperti pada contoh di bawah ini.
library(tidyverse)
ggplot() +
geom_sf(data=veg, aes(fill =`National_`))
Seandainya kita ingin melakukan cropping, atau membuang sebagian
pengamatan, sesuai dengan batas koordinat tertentu, maka kita bisa
menggunakan fungsi st_crop()
untuk melakukannya. Contohnya,
misalnya kita menginginkan wilayah dengan batas sesuai dengan nilai yang
disimpang pada objek ext
berikut ini.
ext <- c(-66642.18, -3809853.29, -44412.18, -3750723.29)
names(ext) <- c("xmin", "ymin", "xmax", "ymax")
ext
## xmin ymin xmax ymax
## -66642.18 -3809853.29 -44412.18 -3750723.29
Selanjutnya kita akan crop sebagian data pada objek veg
berdasarkan batas yang telah ditetapkan pada objek ext
.
veg <- st_crop(veg, ext)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
ggplot() + geom_sf(data=veg, aes(fill = `National_`))
Sebagai ilustrasi, misalnya kita mengingkan subset dari data menurut
atribut/kolom/peubah National_
seperti di bawah ini.
#Make a vector of the veg types we want
split_veg <- c("Peninsula Granite Fynbos - North",
"Peninsula Granite Fynbos - South",
"Cape Flats Dune Strandveld - West Coast",
"Cape Flats Dune Strandveld - False Bay")
Selanjutnya subset dapat diambil menggunakan tidyverse
seperti pada contoh dibawah ini, lalu dibuat plot dari subset
tersebut.
#Using tidyverse piping to filter and plot
veg %>%
filter(National_ %in% split_veg) %>%
ggplot() +
geom_sf(aes(fill = `National_`))
Misalnya kita ingin menggabungkan kategori
Peninsula Granite Fynbos - North
dan
Peninsula Granite Fynbos - South
menjadi satu yaitu
Peninsula Granite Fynbos
, sedangkan dua kategori lainnya
menjadi Cape Flats Dune Strandveld
.
veg$National_ <- str_replace_all(veg$National_,
c("Peninsula Granite Fynbos - North" = "Peninsula Granite Fynbos",
"Peninsula Granite Fynbos - South" = "Peninsula Granite Fynbos",
"Cape Flats Dune Strandveld - West Coast" = "Cape Flats Dune Strandveld",
"Cape Flats Dune Strandveld - False Bay" = "Cape Flats Dune Strandveld"))
veg %>% group_by(National_) %>%
summarize() %>%
ggplot() + geom_sf(aes(fill = National_))
Fitur iNaturalist dapat diakses langsung melalui R menggunakan
package rinat
.
library(rinat)
#Call the data directly from iNat
pc <- get_inat_obs(taxon_name = "Protea cynaroides",
bounds = c(-35, 18, -33.5, 18.5),
maxresults = 1000)
#View the first few rows of data
head(pc)
#Filter returned observations by a range of column attribute criteria
pc <- pc %>% filter(positional_accuracy<46 &
latitude<0 &
!is.na(latitude) &
captive_cultivated == "false" &
quality_grade == "research")
class(pc)
## [1] "data.frame"
Seperti terlihat pada keluaran di atas, objek pc
merupakan kelas data frame, dimana terdapat kolom koordinat bujur dan
lintang di dalamnya. Namun, R belum mengenali objek tersebut sebagai
objek spasial. Konversi data frame menjadi objek spasial dapat dilakukan
menggunakan fungsi st_as_sf()
.
#Make the dataframe a spatial object of class = "sf"
pc <- st_as_sf(pc, coords = c("longitude", "latitude"), crs = 4326)
class(pc)
## [1] "sf" "data.frame"
names(pc)
## [1] "scientific_name" "datetime"
## [3] "description" "place_guess"
## [5] "tag_list" "common_name"
## [7] "url" "image_url"
## [9] "user_login" "id"
## [11] "species_guess" "iconic_taxon_name"
## [13] "taxon_id" "num_identification_agreements"
## [15] "num_identification_disagreements" "observed_on_string"
## [17] "observed_on" "time_observed_at"
## [19] "time_zone" "positional_accuracy"
## [21] "public_positional_accuracy" "geoprivacy"
## [23] "taxon_geoprivacy" "coordinates_obscured"
## [25] "positioning_method" "positioning_device"
## [27] "user_id" "user_name"
## [29] "created_at" "updated_at"
## [31] "quality_grade" "license"
## [33] "sound_url" "oauth_application_id"
## [35] "captive_cultivated" "geometry"
Selanjutnya, kita dapat membuat visualisasi dari objek
pc
, yang telah memasukkan informasi spasial di
dalamnya.
#Plot
ggplot() + geom_sf(data=pc)
Lebih jauh lagi, kita dapat menambahkan base map pada visualisasi di atas, untuk memudahkan interpretasi.
#install.packages(c("rosm", "ggspatial", "prettymapr"))
library(rosm)
library(ggspatial)
ggplot() +
annotation_map_tile(type = "osm", progress = "none") +
geom_sf(data=pc)
#install.packages(c("leaflet", "htmltools"))
library(leaflet)
library(htmltools)
leaflet() %>%
# Add default OpenStreetMap map tiles
addTiles(group = "Default") %>%
# Add our points
addCircleMarkers(data = pc,
group = "Protea cynaroides",
radius = 3,
color = "green")
#install.packages("terra")
library(terra)
## terra 1.7.65
##
## Attaching package: 'terra'
## The following object is masked from 'package:tidyr':
##
## extract
dem <- rast("cape_peninsula/CoCT_10m.tif")
class(dem)
## [1] "SpatRaster"
## attr(,"package")
## [1] "terra"
dem
## class : SpatRaster
## dimensions : 9902, 6518, 1 (nrow, ncol, nlyr)
## resolution : 10, 10 (x, y)
## extent : -64180, 1000, -3804020, -3705000 (xmin, xmax, ymin, ymax)
## coord. ref. : GCS_WGS_1984
## source : CoCT_10m.tif
## name : 10m_BA
## min value : -35
## max value : 1590
Untuk memastikan informasi tentang CRS dan proyeksi yang digunakan
pada objek dem
, kita dapat menggunakan fungsi
crs()
.
crs(dem)
## [1] "PROJCRS[\"GCS_WGS_1984\",\n BASEGEOGCRS[\"WGS 84\",\n DATUM[\"World Geodetic System 1984\",\n ELLIPSOID[\"WGS 84\",6378137,298.25722356049,\n LENGTHUNIT[\"metre\",1]]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n ID[\"EPSG\",4326]],\n CONVERSION[\"Transverse Mercator\",\n METHOD[\"Transverse Mercator\",\n ID[\"EPSG\",9807]],\n PARAMETER[\"Latitude of natural origin\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8801]],\n PARAMETER[\"Longitude of natural origin\",19,\n ANGLEUNIT[\"degree\",0.0174532925199433],\n ID[\"EPSG\",8802]],\n PARAMETER[\"Scale factor at natural origin\",1,\n SCALEUNIT[\"unity\",1],\n ID[\"EPSG\",8805]],\n PARAMETER[\"False easting\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8806]],\n PARAMETER[\"False northing\",0,\n LENGTHUNIT[\"metre\",1],\n ID[\"EPSG\",8807]]],\n CS[Cartesian,2],\n AXIS[\"easting\",east,\n ORDER[1],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]],\n AXIS[\"northing\",north,\n ORDER[2],\n LENGTHUNIT[\"metre\",1,\n ID[\"EPSG\",9001]]]]"
dem <- crop(dem, ext(c(-66642.18, -44412.18, -3809853.29, -3750723.29)))
dem
## class : SpatRaster
## dimensions : 5330, 1977, 1 (nrow, ncol, nlyr)
## resolution : 10, 10 (x, y)
## extent : -64180, -44410, -3804020, -3750720 (xmin, xmax, ymin, ymax)
## coord. ref. : GCS_WGS_1984
## source(s) : memory
## varname : CoCT_10m
## name : 10m_BA
## min value : -15
## max value : 1084
Misalnya, kita ingin melakukan agregrasi data, yaitu dengan
menggabungkan 9 pixel (3x3) menjadi 1 pixel. Kita dapat menggunakan
fungi aggregate()
seperti contoh di bawah ini.
dem30 <- aggregate(dem, fact = 3, fun = mean)
##
|---------|---------|---------|---------|
=========================================
dem30
## class : SpatRaster
## dimensions : 1777, 659, 1 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : -64180, -44410, -3804030, -3750720 (xmin, xmax, ymin, ymax)
## coord. ref. : GCS_WGS_1984
## source(s) : memory
## name : 10m_BA
## min value : -15.000
## max value : 1083.556
plot(dem30)
Atau bisa juga menggunakan ggplot seperti pada contoh di bawah ini.
#call tidyverse libraries and plot
library(tidyverse)
names(dem30)
## [1] "10m_BA"
dem30 %>% as.data.frame(xy = TRUE) %>%
ggplot() +
geom_raster(aes(x = x, y = y, fill = `10m_BA`)) + coord_fixed()
Berikut ini adalah plot dari data awal, sebelum dilakukan agregasi.
dem %>%
as.data.frame(xy = TRUE) %>%
ggplot() +
geom_raster(aes(x = x, y = y, fill = `10m_BA`)) + coord_fixed()
Sebelum menggabungkan beberapa data, berikut ini disajikan contoh jika kita ingin mengubah data raster menjadi titik.
library(rinat)
library(sf)
#Call data for two species directly from iNat
pc <- get_inat_obs(taxon_name = "Protea cynaroides",
bounds = c(-35, 18, -33.5, 18.5),
maxresults = 1000)
ll <- get_inat_obs(taxon_name = "Leucadendron laureolum",
bounds = c(-35, 18, -33.5, 18.5),
maxresults = 1000)
#Combine the records into one dataframe
pc <- rbind(pc,ll)
#Filter returned observations by a range of attribute criteria
pc <- pc %>% filter(positional_accuracy<46 &
latitude<0 &
!is.na(latitude) &
captive_cultivated == "false" &
quality_grade == "research")
#Make the dataframe a spatial object of class = "sf"
pc <- st_as_sf(pc, coords = c("longitude", "latitude"), crs = 4326)
#Set to the same projection as the elevation data
pc <- st_transform(pc, crs(dem30))
Sebelum menggabungkan beberapa data, berikut ini disajikan contoh jika kita ingin mengubah data raster menjadi vektor.
#Make the vegetation type a factor
veg$National_ <- as.factor(veg$National_)
#Rasterize
vegras <- rasterize(vect(veg), dem30, field = "National_")
#Plot
vegras %>%
as.data.frame(xy = TRUE) %>%
ggplot() +
geom_raster(aes(x = x, y = y, fill = National_)) + coord_fixed()
Selanjutnya, kita gabungkan beberapa objek yang telah kita simpan sebelumnya, ke dalam satu peta.
ggplot() +
geom_raster(data = as.data.frame(vegras, xy = TRUE),
aes(x = x, y = y, fill = National_)) +
geom_contour(data = as.data.frame(dem30, xy = TRUE),
aes(x = x, y = y, z = `10m_BA`), breaks = seq(0, 1100, 100), colour = "black") +
geom_sf(data=pc, colour = "white", size = 0.5)
Ada banyak hal yang dapat dicoba lebih lanjut tentang bagaimana membaca dan mengolah data spasial menggunakan R. Silahkan mempelajari hal-hal yang tidak tercakup pada modul ini pada referensi yang tercantum di bawah ini. Semoga bermanfaat!
Brazil, N. (2023). Lab 3: Spatial Data in R. https://crd230.github.io/lab3.html (accessed at 23 January 2024)
Slingsby, J. (2023). A Minimal Introduction to GIS (in R). Retrieved from: https://www.ecologi.st/spatial-r/r-as-a-gis.html. (accessed at 24 January 2024)
https://tmieno2.github.io/R-as-GIS-for-Economists/before-you-start-1.html