Analisa Pola Titik Spasial

Pola titik dalam ruang spasial dibagi menjadi 3 jenis yaitu:

  1. Acak : setiap titik mempunyai peluang yang sama untuk menduduki suatu ruang dan tidak dipengaruhi oleh titik yang lain
  2. Uniform : setiap titik adalah sejauh mungkin dari titik-titik tetangganya.
  3. Cluster : Banyak titik terkonsentrasi menduduki pada ruang yang sama, dan ruang yang lain sangat sedikit ditempati oleh titik.

Dalam menentukan pola titik digunakan dua pendekatan, yaitu :

  1. Metode Kuadran
  2. Empirical K-Function

Adapun tahapan analisa pola titik dalam ruang spasial sebagai berikut :

Package

Berikut package yang digunakan:

library(sf) #Mengelola data spasial dengan standar Simple Features (sf)
## Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE
library(dplyr)#Manipulasi data seperti filter, select, mutate, dan summarise
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)  # Membuat grafik statistik dengan pendekatan Grammar of Graphics
library(spatstat.geom)     # ppp, owin, quadratcount, as.ppp
## Loading required package: spatstat.data
## Loading required package: spatstat.univar
## spatstat.univar 3.1-4
## spatstat.geom 3.5-0
library(spatstat.explore)  # Kest, Lest, quadrat.test
## Loading required package: spatstat.random
## spatstat.random 3.4-1
## Loading required package: nlme
## 
## Attaching package: 'nlme'
## The following object is masked from 'package:dplyr':
## 
##     collapse
## spatstat.explore 3.5-2
library(rosm)
library(ggspatial)

1. Import Data

Data yang digunakan adalah data inaturalist yang dapat diakses langsung menggunakan package rinat.

library(rinat) #Mengambil data naturalis
pc <- get_inat_obs(taxon_name = "Protea cynaroides",
                   bounds = c(-35, 18, -33.5, 18.5),
                   maxresults = 1000)
head(pc)
##     scientific_name                  datetime       description
## 1 Protea cynaroides 2025-09-11 12:32:57 +0200                  
## 2 Protea cynaroides 2025-09-10 11:20:48 +0200                  
## 3 Protea cynaroides 2025-09-10 10:45:06 +0200                  
## 4 Protea cynaroides 2025-09-10 10:04:21 +0200                  
## 5 Protea cynaroides 2025-09-05 17:05:00 +0200                  
## 6 Protea cynaroides 2025-08-21 11:03:34 +0200 Botanical Gardens
##                                             place_guess  latitude longitude
## 1          Circular Drive, Cape Point, Western Cape, ZA -34.29180  18.43589
## 2 Silver Mine (Nature Reserve), Cape Town, South Africa -34.10265  18.44050
## 3   Muizenberg Mountains, Cape Town, 7945, South Africa -34.09606  18.44572
## 4     Table Mountain National Park, ZA-WC-CT, ZA-WC, ZA -34.09361  18.43426
## 5 Silver Mine (Nature Reserve), Cape Town, South Africa -34.07445  18.39816
## 6         Wynberg NU (2), Cape Town, 7824, South Africa -33.98979  18.42769
##   tag_list common_name                                                url
## 1          King Protea https://www.inaturalist.org/observations/313170699
## 2          King Protea https://www.inaturalist.org/observations/312964582
## 3          King Protea https://www.inaturalist.org/observations/312963501
## 4          King Protea https://www.inaturalist.org/observations/312962228
## 5          King Protea https://www.inaturalist.org/observations/312641000
## 6          King Protea https://www.inaturalist.org/observations/309437763
##                                                                    image_url
## 1 https://inaturalist-open-data.s3.amazonaws.com/photos/565512840/medium.jpg
## 2 https://inaturalist-open-data.s3.amazonaws.com/photos/565119182/medium.jpg
## 3 https://inaturalist-open-data.s3.amazonaws.com/photos/565117193/medium.jpg
## 4 https://inaturalist-open-data.s3.amazonaws.com/photos/565114431/medium.jpg
## 5 https://inaturalist-open-data.s3.amazonaws.com/photos/564500630/medium.jpg
## 6 https://inaturalist-open-data.s3.amazonaws.com/photos/558389840/medium.jpg
##       user_login        id species_guess iconic_taxon_name taxon_id
## 1 bobsteelephoto 313170699   King Protea           Plantae   132848
## 2       dryfveer 312964582   King Protea           Plantae   132848
## 3       dryfveer 312963501   King Protea           Plantae   132848
## 4       dryfveer 312962228   King Protea           Plantae   132848
## 5         jrgale 312641000   King Protea           Plantae   132848
## 6       kentashi 309437763   King Protea           Plantae   132848
##   num_identification_agreements num_identification_disagreements
## 1                             1                                0
## 2                             0                                0
## 3                             0                                0
## 4                             0                                0
## 5                             1                                0
## 6                             2                                0
##    observed_on_string observed_on        time_observed_at time_zone
## 1 2025-09-11 12:32:57  2025-09-11 2025-09-11 10:32:57 UTC  Pretoria
## 2 2025-09-10 11:20:48  2025-09-10 2025-09-10 09:20:48 UTC  Pretoria
## 3 2025-09-10 10:45:06  2025-09-10 2025-09-10 08:45:06 UTC  Pretoria
## 4 2025-09-10 10:04:21  2025-09-10 2025-09-10 08:04:21 UTC  Pretoria
## 5  2025/09/05 5:05 PM  2025-09-05 2025-09-05 15:05:00 UTC  Pretoria
## 6 2025-08-21 11:03:34  2025-08-21 2025-08-21 09:03:34 UTC  Pretoria
##   positional_accuracy public_positional_accuracy geoprivacy taxon_geoprivacy
## 1                   6                          6                        open
## 2                   4                          4                        open
## 3                   4                          4                        open
## 4                   4                          4                        open
## 5                  15                         15                        open
## 6                 104                        104                        open
##   coordinates_obscured positioning_method positioning_device user_id
## 1                false                                       3047144
## 2                false                                       2173153
## 3                false                                       2173153
## 4                false                                       2173153
## 5                false                                       3762511
## 6                false                gps                gps 9681215
##       user_name              created_at              updated_at quality_grade
## 1    Bob Steele 2025-09-11 19:16:19 UTC 2025-09-11 23:53:44 UTC      research
## 2  Santie Gouws 2025-09-10 19:20:01 UTC 2025-09-10 19:20:39 UTC      needs_id
## 3  Santie Gouws 2025-09-10 19:14:17 UTC 2025-09-10 19:14:59 UTC      needs_id
## 4  Santie Gouws 2025-09-10 19:07:32 UTC 2025-09-10 19:08:18 UTC      needs_id
## 5     John Gale 2025-09-09 08:57:34 UTC 2025-09-09 09:31:03 UTC      research
## 6 Kent Jennings 2025-08-27 08:26:12 UTC 2025-09-01 13:44:16 UTC        casual
##    license sound_url oauth_application_id captive_cultivated
## 1 CC-BY-NC        NA                  843              false
## 2 CC-BY-NC        NA                    2              false
## 3 CC-BY-NC        NA                    2              false
## 4 CC-BY-NC        NA                    2              false
## 5 CC-BY-NC        NA                   NA              false
## 6 CC-BY-NC        NA                    2               true
names(pc)
##  [1] "scientific_name"                  "datetime"                        
##  [3] "description"                      "place_guess"                     
##  [5] "latitude"                         "longitude"                       
##  [7] "tag_list"                         "common_name"                     
##  [9] "url"                              "image_url"                       
## [11] "user_login"                       "id"                              
## [13] "species_guess"                    "iconic_taxon_name"               
## [15] "taxon_id"                         "num_identification_agreements"   
## [17] "num_identification_disagreements" "observed_on_string"              
## [19] "observed_on"                      "time_observed_at"                
## [21] "time_zone"                        "positional_accuracy"             
## [23] "public_positional_accuracy"       "geoprivacy"                      
## [25] "taxon_geoprivacy"                 "coordinates_obscured"            
## [27] "positioning_method"               "positioning_device"              
## [29] "user_id"                          "user_name"                       
## [31] "created_at"                       "updated_at"                      
## [33] "quality_grade"                    "license"                         
## [35] "sound_url"                        "oauth_application_id"            
## [37] "captive_cultivated"

Lakukan Filter pada data dengan kriteria tertentu supaya bebas noise.

pc <- pc %>%
  filter(
    !is.na(latitude), !is.na(longitude),
    positional_accuracy < 46,         # akurasi posisi <= 46 m
    latitude < 0,                     # belahan selatan (cek saja)
    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().

2. Mengubah data frame ke dalam sf point (ppp)

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"

3. Membuat visualisasi

ggplot() +
  annotation_map_tile(type = "osm", progress = "none") +
  geom_sf(data = pc, size = 1) +
  labs(title = "Observasi iNaturalist: Protea cynaroides",
       subtitle = "Cape Peninsula (WGS84 lon/lat)")

4. Menyiapkan window dan konversi ke Pola Titik (ppp)

# a) Jendela dari bounding box data
bbox_ll <- st_bbox(pc)  # dalam lon/lat
# b) Untuk K-function: reproject ke UTM (meter). Cape Town ~ UTM 34S = EPSG:32734
pc_utm <- st_transform(pc, 32734)
bbox_utm <- st_bbox(pc_utm)

# Buat window (owin) dan objek ppp (meter)
win_utm <- owin(xrange = c(bbox_utm["xmin"], bbox_utm["xmax"]),
                yrange = c(bbox_utm["ymin"], bbox_utm["ymax"]))

coords <- st_coordinates(pc_utm)

X <- ppp(x = coords[,1], y = coords[,2], window = win_utm)
## Warning: data contain duplicated points

Karena data x masih mengandung duplikat maka hapus terlebih dahulu :

X <- unique(X)  # unique.ppp: singkirkan duplikat di objek ppp
X
## Planar point pattern: 661 points
## window: rectangle = [253937.34, 266793.64] x [6201377, 6242922] units

5. Identifikasi Pola Titik

1. Metode GRID/Quadrat

q <- quadratcount(X)
q                # hitungannya
##                        x
## y                       [2.54e+05,2.57e+05] (2.57e+05,2.59e+05]
##   (6.235e+06,6.243e+06]                   0                  31
##   (6.226e+06,6.235e+06]                   1                  51
##   (6.218e+06,6.226e+06]                  13                   2
##   (6.21e+06,6.218e+06]                    0                   8
##   [6.201e+06,6.21e+06]                    0                   0
##                        x
## y                       (2.59e+05,2.62e+05] (2.62e+05,2.64e+05]
##   (6.235e+06,6.243e+06]                 158                  74
##   (6.226e+06,6.235e+06]                  65                   3
##   (6.218e+06,6.226e+06]                  26                  88
##   (6.21e+06,6.218e+06]                   23                   0
##   [6.201e+06,6.21e+06]                    5                  46
##                        x
## y                       (2.64e+05,2.67e+05]
##   (6.235e+06,6.243e+06]                   3
##   (6.226e+06,6.235e+06]                   0
##   (6.218e+06,6.226e+06]                  47
##   (6.21e+06,6.218e+06]                    1
##   [6.201e+06,6.21e+06]                   16
plot(q, main = "Quadrat counts (5 x 5, UTM meters)")
plot(X, add=T, pch=20, cex = 0.5)

Melakukan uji hipotesis CSR berbasis Quadrat

qt <- quadrat.test(X, nx = 5, ny = 5)
qt
## 
##  Chi-squared test of CSR using quadrat counts
## 
## data:  X
## X2 = 1307.2, df = 24, p-value < 2.2e-16
## alternative hypothesis: two.sided
## 
## Quadrats: 5 by 5 grid of tiles

Kesimpulan :

- H0: CSR (Complete Spatial Randomness ~ proses Poisson homogen)

- Jika p-value kecil (<0.05), tolak H0 → pola tidak acak (clustered atau regular).

- Karena p-value <0.05 artinya tolak H0 sehingga pola titik bersifat tidak acak ( bisa begerombol atau reguler)

2. Metode K-Function (Ripley)

K <- Kest(X, correction = "Ripley")
plot(K, main = "Ripley's K (meter)", legend=FALSE)

E<-envelope(X,Kest, nsim=99)
## Generating 99 simulations of CSR  ...
## 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, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
## 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
## 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
## 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 
## 99.
## 
## Done.
plot(E)

mad.test(X, Kest, nsim=99, alternative="two.sided")
## Generating 99 simulations of CSR  ...
## 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, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
## 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
## 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
## 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 
## 99.
## 
## Done.
## 
##  Maximum absolute deviation test of CSR
##  Monte Carlo test based on 99 simulations
##  Summary function: K(r)
##  Reference function: theoretical
##  Alternative: two.sided
##  Interval of distance values: [0, 3214.07437876331]
##  Test statistic: Maximum absolute deviation
##  Deviation = observed minus theoretical
## 
## data:  X
## mad = 77709583, rank = 1, p-value = 0.01

Kesimpulan :

Dengan pendekatan K-Function, diperoleh plot data observasi atau data empiris berada diatas plot garis Poisson dan nilai p-value < 0,05 yang berarti Tolak Ho, sehingga dapat dikatakan bahwa pola titik menyebar secara bekelompok (clustered)