Bagaimana melakukan analisis spasial di R dengan sf

Di mana Anda memilih? Siapa Anda legislator? Apa kode pos Anda? Pertanyaan-pertanyaan ini memiliki kesamaan geospasial: Jawabannya melibatkan penentuan di dalam poligon mana sebuah titik berada.

Perhitungan seperti itu sering kali dilakukan dengan perangkat lunak GIS khusus. Tapi itu juga mudah dilakukan di R. Anda memerlukan tiga hal:

  1. Cara untuk geocode alamat untuk menemukan lintang dan bujur; 
  2. Shapefiles yang menguraikan batas poligon kode pos; dan 
  3. Paket sf.

Untuk geocoding, saya biasanya menggunakan geocod.io API. Ini gratis untuk 2.500 pencarian sehari dan memiliki paket R yang bagus, tetapi Anda memerlukan kunci API (gratis) untuk menggunakannya. Untuk mengatasi sedikit kerumitan untuk artikel ini, saya akan menggunakan API Nominatim Open Street Map Open-source gratis. Itu tidak membutuhkan kunci. Paket tmaptools memiliki fungsi geocode_OSM(),, untuk menggunakan API itu.

Mengimpor dan menyiapkan data geospasial

Saya akan menggunakan paket sf, tmaptools, tmap, dan dplyr. Jika Anda ingin mengikuti, muat masing-masing dengan pacman::p_load()atau instal apa pun yang belum ada di sistem Anda install.packages(), lalu muat masing-masing dengan library().

Untuk contoh ini, saya akan membuat vektor dengan dua alamat, kantor kami di Framingham, Massachusetts, dan kantor RStudio di Boston.

alamat <- c ("492 Old Connecticut Path, Framingham, MA",

"250 Northern Ave., Boston, MA")

Geocoding sangat mudah dengan geocode_OSM. Anda dapat melihat hasilnya dengan mencetak tiga kolom pertama termasuk lintang dan bujur:

geocoded_addresses <- geocode_OSM (alamat)

cetak (geocoded_addresses [, 1: 3])

kueri lat lon

# 1 492 Old Connecticut Path, Framingham, MA 42.31348 -71.39105

# 2 250 Northern Ave., Boston, MA 42.34806 -71.03673

Ada beberapa cara untuk mendapatkan shapefile kode ZIP. Yang paling mudah mungkin adalah Area Tabulasi Kode Pos Biro Sensus AS, yang mirip jika tidak persis sama dengan batas-batas Layanan Pos AS.

Anda dapat mengunduh file ZCTA langsung dari Biro Sensus AS, tetapi itu adalah file untuk seluruh negara. Lakukan itu hanya jika Anda tidak keberatan dengan file data yang besar. 

Satu tempat untuk mengunduh file ZCTA untuk satu negara bagian adalah Pelapor Sensus. Telusuri data apa pun menurut negara bagian, seperti populasi, lalu tambahkan kode pos ke geografi dan pilih unduh data sebagai shapefile.

Saya dapat mengekstrak file yang saya unduh secara manual, tetapi lebih mudah di R. Di sini saya menggunakan unzip()fungsi basis R pada file yang diunduh, dan mengekstraknya ke subdirektori proyek bernama ma_zip_shapefile. Itu junkpaths = TRUEargumen bilang aku tidak ingin unzip menambahkan subdirektori lain berdasarkan nama file zip.

unzip ("data / acs2017_5yr_B01003_86000US02648.zip",

exdir = "ma_zip_shapefile", junkpaths = TRUE,

timpa = BENAR)

Impor dan analisis geospasial dengan sf

Sekarang akhirnya beberapa pekerjaan geospasial. Saya akan mengimpor shapefile ke R menggunakan st_read()fungsi sf .

zipcode_geo <- st_read ("ma_zip_shapefile / acs2017_5yr_B01003_86000US02648.shp") # Reading layer `acs2017_5yr_B01003_86000US02648 'dari sumber data` /Users/smachlis/Documents/MoreWithRUS017_48.shp_shap1003 dengan koleksi fitur `` /Users/smachlis' fitur dan 4 bidang # jenis geometri: MULTIPOLYGON # dimensi: XY # bbox: xmin: -73.50821 ymin: 41.18705 xmax: -69.85886 ymax: 42.95774 # epsg (SRID): 4326 # proj4string: + proj = longlat + datum = WGS84 + no_defs

Saya telah menyertakan respons konsol saat berjalan st_read()karena ada beberapa informasi yang ditampilkan di sana: epsg. Yang mengatakan sistem referensi koordinat apa yang digunakan untuk membuat file . Ini dia 4326. Tanpa terlalu jauh ke dalam gulma, epsg pada dasarnya menunjukkan  sistem apa yang digunakan untuk menerjemahkan area pada bola tiga dimensi — Bumi — ke koordinat dua dimensi (lintang dan bujur) . Ini penting karena ada banyak sistem referensi koordinat yang berbeda. Saya ingin poligon kode pos dan titik alamat saya menggunakan yang sama, sehingga berbaris dengan benar.

Catatan: File ini kebetulan menyertakan poligon untuk seluruh negara bagian Massachusetts, yang tidak saya perlukan. Jadi saya akan menyaring baris Massachusetts itu dengan

zipcode_geo <- dplyr :: filter (zipcode_geo,

nama! = "Massachusetts")

Memetakan shapefile dengan tmap

Memetakan data poligon tidak diperlukan, tetapi ini adalah pemeriksaan yang bagus untuk shapefile saya untuk melihat apakah geometri itu yang saya harapkan. Anda dapat melakukan plot cepat dari objek sf dengan fungsi tmap qtm()(singkatan dari quick theme map).

qtm (zipcode_geo) +

tm_legend (show = FALSE)

Layar yang diambil oleh Sharon Machlis,

Dan sepertinya saya memang memiliki geometri Massachusetts dengan poligon yang dapat berupa kode pos.

Selanjutnya saya ingin menggunakan data alamat geocoded. Ini saat ini berupa bingkai data biasa, tetapi perlu diubah menjadi objek geospasial sf dengan sistem koordinat yang tepat.

Kita bisa melakukannya dengan st_as_sf()fungsi sf . (Catatan: fungsi paket sf yang beroperasi pada data spasial dimulai dengan st_, yang merupakan singkatan dari "spasial" dan "temporal.")

st_as_sf()membutuhkan beberapa argumen. Pada kode di bawah ini, argumen pertama adalah objek yang akan diubah — alamat geocode saya. Vektor argumen kedua memberi tahu fungsi kolom mana yang memiliki nilai x (bujur) dan y (lintang). Yang ketiga menetapkan sistem referensi koordinat ke 4326, jadi sama dengan poligon kode pos saya.

point_geo <- st_as_sf (geocoded_addresses,

coords = c (x = "lon", y = "lat"),

crs = 4326)

Geospasial bergabung dengan sf

Sekarang saya telah menyiapkan dua kumpulan data saya, menghitung kode pos untuk setiap alamat dengan mudah dengan st_join()fungsi sf . Sintaksnya:

st_join (point_sf_object, polygon_sf_object, join = join_type)

In this example, I want to run st_join() on the geocoded points first and the ZIP code polygons second. It’s a so-called left join format: All points in the first data (geocoded addresses) are included, but only points in the second (ZIP code) data that match. Finally, my join type is st_within, since I want the match to be points within. 

my_results <- st_join(point_geo, zipcode_geo,

join = st_within)

That’s it! Now if I look at my results by printing out several of the most important columns, you”ll see each address has a ZIP code (in the “name” column). 

print(my_results[,c("query", "name", "geometry")])

# Kumpulan fitur sederhana dengan 2 fitur dan 2 bidang # tipe geometri: POINT # dimensi: XY # bbox: xmin: -71.39105 ymin: 42.31348 xmax: -71.03673 ymax: 42.34806 # epsg (SRID): 4326 # proj4string: + proj = longlat + datum = WGS84 + no_defs # geometri nama kueri # 1 492 Old Connecticut Path, Framingham, MA 01701 POINT (-71.39105 42.31348) # 2 250 Northern Ave., Boston, MA 02210 POINT (-71.03673 42.34806)

Memetakan titik dan poligon dengan tmap

Jika Anda ingin memetakan titik dan poligon, berikut salah satu cara melakukannya dengan tmap:

tm_shape (zipcode_geo) +

tm_fill () +

tm_shape (hasil_saya) +

tm_bubbles (col = "red", size = 0.25)

Tangkapan layar oleh Sharon Machlis,

Ingin lebih banyak kiat R? Buka halaman "Lakukan Lebih Banyak dengan R"!