sfarrow
は、座標参照系情報を維持したまま、Parquetファイルから/への「シンプルフィーチャ」形式の空間ベクタデータの読み書きを支援するために設計されている。基本的に、このツールは、R
のオブジェクトを接続しようとするものである。 sf
と arrow
にある https://arrow.apache.org/docs/r/
オブジェクトを接続しようとしており、その内部動作のためにこれらのパッケージに依存している。
主な目的は、Parquet
ファイル内の空間データの相互運用性をサポートすることである。Rオブジェクト
( sf
を含む) は arrow
でファイルに書き込むことができる。しかし、これらは必ずしも空間情報を保持しておらず、Pythonで読み込むことができない。sfarrow
は Python GeoPandas
でも使われているメタデータ形式を実装しており、ここで説明されている。 https://github.com/geopandas/geo-arrow-spec。
これらのメタデータはまだ安定していないことに注意。sfarrow
は変更される可能性があることを警告している。
# install from CRAN with install.packages('sfarrow')
# or install from devtools::install_github("wcjochem/sfarrow@main)
# load the library
library(sfarrow)
library(dplyr, warn.conflicts = FALSE)
Parquetファイル(拡張子は .parquet
)は、st_read_parquet()
を使って読み込むことができ、ファイルシステムを指すことができる。これにより、sf
空間データオブジェクトがメモリ上に作成され、sf
からの関数を使用して通常通り使用することができる。
# read an example dataset created from Python using geopandas
<- st_read_parquet(system.file("extdata", "world.parquet", package = "sfarrow"))
world
class(world)
#> [1] "sf" "data.frame"
world#> Simple feature collection with 177 features and 5 fields
#> Geometry type: GEOMETRY
#> Dimension: XY
#> Bounding box: xmin: -180 ymin: -90 xmax: 180 ymax: 83.64513
#> Geodetic CRS: WGS 84
#> First 10 features:
#> pop_est continent name iso_a3 gdp_md_est
#> 1 920938 Oceania Fiji FJI 8.374e+03
#> 2 53950935 Africa Tanzania TZA 1.506e+05
#> 3 603253 Africa W. Sahara ESH 9.065e+02
#> 4 35623680 North America Canada CAN 1.674e+06
#> 5 326625791 North America United States of America USA 1.856e+07
#> 6 18556698 Asia Kazakhstan KAZ 4.607e+05
#> 7 29748859 Asia Uzbekistan UZB 2.023e+05
#> 8 6909701 Oceania Papua New Guinea PNG 2.802e+04
#> 9 260580739 Asia Indonesia IDN 3.028e+06
#> 10 44293293 South America Argentina ARG 8.794e+05
#> geometry
#> 1 MULTIPOLYGON (((180 -16.067...
#> 2 POLYGON ((33.90371 -0.95, 3...
#> 3 POLYGON ((-8.66559 27.65643...
#> 4 MULTIPOLYGON (((-122.84 49,...
#> 5 MULTIPOLYGON (((-122.84 49,...
#> 6 POLYGON ((87.35997 49.21498...
#> 7 POLYGON ((55.96819 41.30864...
#> 8 MULTIPOLYGON (((141.0002 -2...
#> 9 MULTIPOLYGON (((141.0002 -2...
#> 10 MULTIPOLYGON (((-68.63401 -...
plot(sf::st_geometry(world))
同様に、sf
オブジェクトから、st_write_parquet()
を使用して、新しいファイルへのパスを指定して Parquet
ファイルを書き込むことができる。非空間オブジェクトは
sfarrow
では書き込めないので、代わりに arrow
を使う必要がある。
# output the file to a new location
# note the warning about possible future changes in metadata.
st_write_parquet(world, dsn = file.path(tempdir(), "new_world.parquet"))
#> Warning: This is an initial implementation of Parquet/Feather file support and
#> geo metadata. This is tracking version 0.1.0 of the metadata
#> (https://github.com/geopandas/geo-arrow-spec). This metadata
#> specification may change and does not yet make stability promises. We
#> do not yet recommend using this in a production setting unless you are
#> able to rewrite your Parquet/Feather files.
Parquet ファイルの読み書きも良いが、arrow
の真の力は、大きなデータセットを、クエリをより速く実行するための基準に基づいて複数のファイル、つまりパーティションに分割することにある。現在
sfarrow
では、マルチファイルの空間データセットに対する基本的なサポートがある。その他のデータセットクエリーオプションについては、arrow
[documentation] (https://arrow.apache.org/docs/r/articles/dataset.html)を参照。
sfarrow
は arrows
の dplyr
インターフェースにアクセスし、パーティショニングされた Arrow
データセットを探索する {#querying-and-reading-datasets
-sfarrow-accesses-arrows’s-dplyr-interface-to-explore-partitioned-arrow
-datasets.}
この例では、nc.shpファイルをランダムに3つのグループに分割し、さらにランダムに2つのグループに分割して作成したデータセットを使用することにする。これにより、ネストされたファイル群が作成される。
list.files(system.file("extdata", "ds", package = "sfarrow"), recursive = TRUE)
#> [1] "split1=1/split2=1/part-3.parquet" "split1=1/split2=2/part-0.parquet"
#> [3] "split1=2/split2=1/part-1.parquet" "split1=2/split2=2/part-5.parquet"
#> [5] "split1=3/split2=1/part-2.parquet" "split1=3/split2=2/part-4.parquet"
ファイルツリーは、データが変数 “split1” と “split2” によって分割されたことを示している。これはランダム分割に使用された列名である。このパーティショニングは “Hive style” にあり、パーティショニングの変数はパスの中に入っている。
まず、arrow
を使ってデータセットを開く。
<- arrow::open_dataset(system.file("extdata", "ds", package="sfarrow")) ds
小さなデータセット (この例のように) の場合、ファイルセット全体を
sf
オブジェクトに読み込むことができる。
<- read_sf_dataset(ds)
nc_ds
nc_ds#> Simple feature collection with 100 features and 16 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS: NAD27
#> First 10 features:
#> AREA PERIMETER CNTY_ CNTY_ID NAME FIPS FIPSNO CRESS_ID BIR74 SID74
#> 1 0.097 1.670 1833 1833 Hertford 37091 37091 46 1452 7
#> 2 0.062 1.547 1834 1834 Camden 37029 37029 15 286 0
#> 3 0.109 1.325 1841 1841 Person 37145 37145 73 1556 4
#> 4 0.081 1.288 1880 1880 Watauga 37189 37189 95 1323 1
#> 5 0.044 1.158 1887 1887 Chowan 37041 37041 21 751 1
#> 6 0.086 1.267 1893 1893 Yadkin 37197 37197 99 1269 1
#> 7 0.170 1.680 1903 1903 Guilford 37081 37081 41 16184 23
#> 8 0.118 1.601 1946 1946 Madison 37115 37115 58 765 2
#> 9 0.134 1.755 1958 1958 Burke 37023 37023 12 3573 5
#> 10 0.116 1.664 1964 1964 McDowell 37111 37111 56 1946 5
#> NWBIR74 BIR79 SID79 NWBIR79 split1 split2 geometry
#> 1 954 1838 5 1237 1 1 MULTIPOLYGON (((-76.74506 3...
#> 2 115 350 2 139 1 1 MULTIPOLYGON (((-76.00897 3...
#> 3 613 1790 4 650 1 1 MULTIPOLYGON (((-78.8068 36...
#> 4 17 1775 1 33 1 1 MULTIPOLYGON (((-81.80622 3...
#> 5 368 899 1 491 1 1 MULTIPOLYGON (((-76.68874 3...
#> 6 65 1568 1 76 1 1 MULTIPOLYGON (((-80.49554 3...
#> 7 5483 20543 38 7089 1 1 MULTIPOLYGON (((-79.53782 3...
#> 8 5 926 2 3 1 1 MULTIPOLYGON (((-82.89597 3...
#> 9 326 4314 15 407 1 1 MULTIPOLYGON (((-81.81628 3...
#> 10 134 2215 5 128 1 1 MULTIPOLYGON (((-81.81628 3...
大規模なデータセットでは、クエリを実行して、パーティショニングされたレコードの縮小セットを返したい場合が多くなる。クエリを作成する最も簡単な方法は、パーティショニング
(および/または他の) 変数で dplyr::filter()
を使用して行をサブセットし、dplyr::select()
を使用して列をサブセットすることである。read_sf_dataset()
は arrow_dplyr_query
を使用して
dplyr::collect()
を呼び出し、アローテーブルを抽出して
sf
に処理することになる。
<- ds %>%
nc_d12 filter(split1 == 1, split2 == 2) %>%
read_sf_dataset()
nc_d12#> Simple feature collection with 20 features and 16 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -83.36472 ymin: 34.71101 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS: NAD27
#> First 10 features:
#> AREA PERIMETER CNTY_ CNTY_ID NAME FIPS FIPSNO CRESS_ID BIR74 SID74
#> 1 0.114 1.442 1825 1825 Ashe 37009 37009 5 1091 1
#> 2 0.143 1.630 1828 1828 Surry 37171 37171 86 3188 5
#> 3 0.153 2.206 1832 1832 Northampton 37131 37131 66 1421 9
#> 4 0.118 1.421 1836 1836 Warren 37185 37185 93 968 4
#> 5 0.114 1.352 1838 1838 Caswell 37033 37033 17 1035 2
#> 6 0.143 1.663 1840 1840 Granville 37077 37077 39 1671 4
#> 7 0.108 1.483 1900 1900 Forsyth 37067 37067 34 11858 10
#> 8 0.111 1.392 1904 1904 Alamance 37001 37001 1 4672 13
#> 9 0.104 1.294 1907 1907 Orange 37135 37135 68 3164 4
#> 10 0.122 1.516 1932 1932 Caldwell 37027 37027 14 3609 6
#> NWBIR74 BIR79 SID79 NWBIR79 split1 split2 geometry
#> 1 10 1364 0 19 1 2 MULTIPOLYGON (((-81.47276 3...
#> 2 208 3616 6 260 1 2 MULTIPOLYGON (((-80.45634 3...
#> 3 1066 1606 3 1197 1 2 MULTIPOLYGON (((-77.21767 3...
#> 4 748 1190 2 844 1 2 MULTIPOLYGON (((-78.30876 3...
#> 5 550 1253 2 597 1 2 MULTIPOLYGON (((-79.53051 3...
#> 6 930 2074 4 1058 1 2 MULTIPOLYGON (((-78.74912 3...
#> 7 3919 15704 18 5031 1 2 MULTIPOLYGON (((-80.0381 36...
#> 8 1243 5767 11 1397 1 2 MULTIPOLYGON (((-79.24619 3...
#> 9 776 4478 6 1086 1 2 MULTIPOLYGON (((-79.01814 3...
#> 10 309 4249 9 360 1 2 MULTIPOLYGON (((-81.32813 3...
plot(sf::st_geometry(nc_d12), col="grey")
select()
を使用して列のサブセットのみを読み込む場合、ジオメトリ列が返されないと、sfarrow
のデフォルトの動作は read_sf_dataset
からのエラーを投げることである。分析にジオメトリ列が必要ない場合は、sfarrow
ではなく、arrow
を使用すれば十分だろう。ただし、read_sf_dataset
で
find_geom = TRUE
を設定すると、選択した列に加え、メタデータ中の任意のジオメトリ列が読み込まれる。
# this command will throw an error
# no geometry column selected for read_sf_dataset
# nc_sub <- ds %>%
# select('FIPS') %>% # subset of columns
# read_sf_dataset()
# set find_geom
<- ds %>%
nc_sub select('FIPS') %>% # subset of columns
read_sf_dataset(find_geom = TRUE)
nc_sub#> Simple feature collection with 100 features and 1 field
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS: NAD27
#> First 10 features:
#> FIPS geometry
#> 1 37157 MULTIPOLYGON (((-79.53051 3...
#> 2 37083 MULTIPOLYGON (((-77.33221 3...
#> 3 37127 MULTIPOLYGON (((-78.18693 3...
#> 4 37199 MULTIPOLYGON (((-82.27921 3...
#> 5 37147 MULTIPOLYGON (((-77.47388 3...
#> 6 37101 MULTIPOLYGON (((-78.53874 3...
#> 7 37013 MULTIPOLYGON (((-77.10377 3...
#> 8 37079 MULTIPOLYGON (((-77.80518 3...
#> 9 37191 MULTIPOLYGON (((-78.16319 3...
#> 10 37123 MULTIPOLYGON (((-80.07141 3...
sf
のオブジェクトを複数のファイルに書き込むには、再度
dplyr::group_by()
を使ってクエリを構築し、パーティショニング変数を定義する。その結果は、sfarrow
に渡される。
%>%
world group_by(continent) %>%
write_sf_dataset(file.path(tempdir(), "world_ds"),
format = "parquet",
hive_style = FALSE)
#> Warning: This is an initial implementation of Parquet/Feather file support and
#> geo metadata. This is tracking version 0.1.0 of the metadata
#> (https://github.com/geopandas/geo-arrow-spec). This metadata
#> specification may change and does not yet make stability promises. We
#> do not yet recommend using this in a production setting unless you are
#> able to rewrite your Parquet/Feather files.
この例では、Hive スタイルを使用していない。このため、パーティショニング変数がフォルダパスに含まれていない。
list.files(file.path(tempdir(), "world_ds"))
#> [1] "Africa" "Antarctica"
#> [3] "Asia" "Europe"
#> [5] "North America" "Oceania"
#> [7] "Seven seas (open ocean)" "South America"
このスタイルのDatasetを読むには、開くときにパーティション変数を指定する必要がある。
::open_dataset(file.path(tempdir(), "world_ds"),
arrowpartitioning = "continent") %>%
filter(continent == "Africa") %>%
read_sf_dataset()
#> Simple feature collection with 51 features and 5 fields
#> Geometry type: GEOMETRY
#> Dimension: XY
#> Bounding box: xmin: -17.62504 ymin: -34.81917 xmax: 51.13387 ymax: 37.34999
#> Geodetic CRS: WGS 84
#> First 10 features:
#> pop_est name iso_a3 gdp_md_est continent
#> 1 53950935 Tanzania TZA 150600.0 Africa
#> 2 603253 W. Sahara ESH 906.5 Africa
#> 3 83301151 Dem. Rep. Congo COD 66010.0 Africa
#> 4 7531386 Somalia SOM 4719.0 Africa
#> 5 47615739 Kenya KEN 152700.0 Africa
#> 6 37345935 Sudan SDN 176300.0 Africa
#> 7 12075985 Chad TCD 30590.0 Africa
#> 8 54841552 South Africa ZAF 739100.0 Africa
#> 9 1958042 Lesotho LSO 6019.0 Africa
#> 10 13805084 Zimbabwe ZWE 28330.0 Africa
#> geometry
#> 1 POLYGON ((33.90371 -0.95, 3...
#> 2 POLYGON ((-8.66559 27.65643...
#> 3 POLYGON ((29.34 -4.499983, ...
#> 4 POLYGON ((41.58513 -1.68325...
#> 5 POLYGON ((39.20222 -4.67677...
#> 6 POLYGON ((24.56737 8.229188...
#> 7 POLYGON ((23.83766 19.58047...
#> 8 POLYGON ((16.34498 -28.5767...
#> 9 POLYGON ((28.97826 -28.9556...
#> 10 POLYGON ((31.19141 -22.2515...