Bagaimana melakukan analisis spatial di R dengan sf

Di mana anda mengundi? Siapa anda penggubal undang-undang? Apakah kod ZIP anda? Soalan-soalan ini mempunyai persamaan geospasial: Jawapannya melibatkan menentukan poligon mana titik jatuh.

Pengiraan sedemikian sering dilakukan dengan perisian GIS khusus. Tetapi mereka juga mudah dilakukan di R. Anda memerlukan tiga perkara:

  1. Cara ke alamat geocode untuk mencari garis lintang dan garis bujur; 
  2. Shapefiles yang menggariskan sempadan poligon kod ZIP; dan 
  3. Pakej sf.

Untuk pengekodan geografi, saya biasanya menggunakan API geocod.io. Ia percuma untuk 2,500 pencarian sehari dan mempunyai pakej R yang bagus, tetapi anda memerlukan kunci API (percuma) untuk menggunakannya. Untuk mengatasi sedikit kerumitan artikel ini, saya akan menggunakan API Nominatim Peta Jalan Terbuka sumber terbuka percuma. Ia tidak memerlukan kunci. Pakej tmaptools mempunyai fungsi geocode_OSM(), untuk menggunakan API itu.

Mengimport dan menyiapkan data geospasial

Saya akan menggunakan pakej sf, tmaptools, tmap, dan dplyr. Sekiranya anda ingin mengikuti, muatkan masing-masing dengan pacman::p_load()atau pasang yang belum ada pada sistem anda install.packages(), kemudian muatkan masing-masing dengan library().

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

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

"250 Northern Ave., Boston, MA")

Geocoding mudah dilakukan dengan geocode_OSM. Anda dapat melihat hasilnya dengan mencetak tiga lajur pertama termasuk garis lintang dan garis bujur:

geocoded_addresses <- geocode_OSM (alamat)

cetak (alamat_kedudukan geografi [, 1: 3])

pertanyaan lat lon

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

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

Terdapat beberapa cara untuk mendapatkan shapefiles kod ZIP. Yang paling mudah ialah Kawasan Tabulasi Kod ZIP Biro Banci AS, yang serupa dengan jika tidak sama dengan sempadan Perkhidmatan Pos AS.

Anda boleh memuat turun fail ZCTA terus dari Biro Banci AS, tetapi fail untuk seluruh negara. Lakukan hanya jika anda tidak keberatan dengan fail data yang besar. 

Satu tempat untuk memuat turun fail ZCTA untuk satu keadaan ialah Census Reporter. Cari data mengikut negeri, seperti populasi, dan kemudian tambahkan kod ZIP ke geografi dan pilih data muat turun sebagai shapefile.

Saya dapat membuka zip fail yang dimuat turun secara manual, tetapi lebih mudah di R. Di sini saya menggunakan unzip()fungsi asas R pada fail yang dimuat turun, dan menyahzipnya ke subdirektori projek yang bernama ma_zip_shapefile. Bahawa junkpaths = TRUEhujah kata saya tidak mahu unzip menambah subdirektori lain berdasarkan nama fail zip.

unzip ("data / acs2017_5yr_B01003_86000US02648.zip",

exdir = "ma_zip_shapefile", junkpaths = BENAR,

ganti = BENAR)

Import dan analisis geospatial dengan sf

Sekarang akhirnya beberapa kerja geospatial. Saya akan mengimport shapefile ke R menggunakan st_read()fungsi sf .

zipcode_geo <- st_read ( "ma_zip_shapefile / acs2017_5yr_B01003_86000US02648.shp") # lapisan Membaca `acs2017_5yr_B01003_86000US02648 'dari sumber data` /Users/smachlis/Documents/MoreWithR/ma_zip_shapefile/acs2017_5yr_B01003_86000US02648.shp' menggunakan pemacu `ESRI shapefile '# koleksi ciri mudah dengan 548 ciri dan 4 medan # 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_d

Saya telah memasukkan respons konsol semasa berjalan st_read()kerana terdapat beberapa maklumat yang dipaparkan di sana: epsg. Yang mengatakan sistem rujukan koordinat apa yang digunakan untuk membuat fail . Ini adalah 4326. Tanpa terlalu jauh ke dalam rumpai, sebuah epsg pada dasarnya menunjukkan  sistem apa yang digunakan untuk menerjemahkan kawasan di dunia tiga dimensi — Bumi — ke koordinat dua dimensi (garis lintang dan garis bujur) . Ini penting kerana terdapat banyak sistem rujukan koordinat yang berbeza. Saya mahu poligon dan titik alamat kod ZIP saya menggunakan yang sama, jadi mereka beratur dengan betul.

Catatan: Fail ini kebetulan merangkumi poligon untuk seluruh negeri Massachusetts, yang saya tidak perlukan. Oleh itu, saya akan menapis Massachusetts itu

zipcode_geo <- dplyr :: filter (zipcode_geo,

nama! = "Massachusetts")

Memetakan shapefile dengan tmap

Pemetaan data poligon tidak perlu, tetapi ini adalah rujukan yang baik dari shapefile saya untuk melihat apakah geometri adalah yang saya harapkan. Anda boleh melakukan plot cepat objek sf dengan fungsi tmap qtm()(ringkas untuk peta tema cepat).

qtm (zipcode_geo) +

tm_legend (tunjukkan = SALAH)

Skrin yang ditembak oleh Sharon Machlis,

Dan nampaknya saya memang mempunyai geometri Massachusetts dengan poligon yang boleh berupa kod ZIP.

Seterusnya saya ingin menggunakan data alamat geoden. Ini pada masa ini kerangka data biasa, tetapi perlu diubah menjadi objek geospasial sf dengan sistem koordinat yang tepat.

Kita boleh melakukannya dengan st_as_sf()fungsi sf . (Catatan: fungsi paket sf yang beroperasi pada data spasial dimulai dengan st_, yang berarti "spatial" dan "temporal.")

st_as_sf()mengambil beberapa hujah. Dalam kod di bawah ini, argumen pertama adalah objek yang hendak diubah — alamat geocoded saya. Vektor argumen kedua memberitahu fungsi lajur mana yang mempunyai nilai x (garis bujur) dan y (garis lintang). Yang ketiga menetapkan sistem rujukan koordinat ke 4326, jadi sama dengan poligon kod ZIP saya.

point_geo <- st_as_sf (alamat_kedudukan geografi,

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

crs = 4326)

Geospatial bergabung dengan sf

Sekarang saya telah menyediakan dua set data saya, mengira kod ZIP untuk setiap alamat adalah mudah dengan st_join()fungsi sf . Sintaks:

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")])

# Koleksi ciri ringkas dengan 2 ciri dan 2 medan # jenis 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 pertanyaan # 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

Sekiranya anda ingin memetakan titik dan poligon, berikut adalah salah satu cara untuk melakukannya dengan tmap:

tm_shape (zipcode_geo) +

tm_fill () +

tm_shape (my_results) +

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

Rakaman skrin oleh Sharon Machlis,

Mahukan lebih banyak petua R? Pergi ke halaman "Lakukan Lebih Banyak dengan R"!