本文へスキップ
からだにいいもの

Rのトピックスを中心に『まだ、まだ、知らない、役に立つ情報?』を発信します。

Rで解析:ggplot2で空間データの不確実性を表現する「ggincerta」パッケージの紹介

「ggincerta」パッケージは、ggplot2に地図の不確実性を表現するレイヤーとスケールを追加するパッケージです。sfの空間データにひもづく推定値と誤差・標準偏差のような2つの数値を1つの塗り色やグリフに統合し、二変量の彩色地図、グリフを使った地図、ランダムな点で敷き詰めたピクセル地図として描き出せます。渡すデータは、ポリゴンごとに推定値と不確実性の指標を持つsfオブジェクトです。ggplot2の上に成り立つ拡張のため、ggplot2でのプロット作成に慣れていることが前提になります。地図で示す数値に誤差や標準偏差が伴う分析を行っている人に向いているのではないかと考えます。

パッケージバージョンは0.2.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。

パッケージのインストール

下記コマンドを実行してください。ggplot2やsfなどの依存パッケージは自動的に導入されます。

# パッケージのインストール
install.packages("ggincerta")


# パッケージの読み込み
library("ggincerta")
Loading required package: ggplot2
スポンサーリンク

コマンド例

詳細はコメント、パッケージのヘルプを確認してください。

ggincertaは、1つの塗り色やグリフで2つの数値を同時に見せることを目指したパッケージです。duo()とduo_pixel()は、推定値と誤差のような2つの数値をひとまとめにしたオブジェクトを作り、aes(fill = …)にそのまま渡せるようにします。geom_sf_dualmap()は塗り色と輪郭色を別々の変数に割り当てて2つの数値を重ねて見せ、geom_sf_glyph()は各領域の代表点に、色と角度で2つの数値を表す図形を置きます。geom_sf_pixel()は各領域の中にランダムな点や六角形のピクセルを敷き詰め、推定値のばらつきを点の散らばりとして表現します。scale_fill_bivariate()とmanual_bivariate_scale()は、これらのレイヤーが使う二変量の配色を組み立てるスケールです。

以降の例では、宇治茶の主産地とされる京都府南部の9市町村(宇治市・宇治田原町・和束町・南山城村・城陽市・京田辺市・木津川市・笠置町・精華町)を、位置関係を簡略化した3行3列の格子状ポリゴンに見立てます。各区画に、年間収穫量の推定値と、調査地点の少なさから生じる標準誤差を持たせた、次の擬似データを共通データとして使います。

# 乱数の種を固定して結果を再現できるようにする
set.seed(20260904)

# 宇治茶の主産地とされる京都府南部の9市町村
tea_areas <- c(
  "宇治市", "宇治田原町", "和束町",
  "南山城村", "城陽市", "京田辺市",
  "木津川市", "笠置町", "精華町"
)

# 位置関係を簡略化した3行3列の格子状ポリゴンを作る
grid <- sf::st_make_grid(
  sf::st_sfc(
    sf::st_polygon(list(rbind(
      c(135.75, 34.72), c(136.05, 34.72),
      c(136.05, 34.96), c(135.75, 34.96),
      c(135.75, 34.72)
    ))),
    crs = 4326
  ),
  n = c(3, 3)
)

# 市町村名、年間収穫量の推定値(トン)、調査地点数から求めた標準誤差を持つsfオブジェクトを作る
tea <- sf::st_sf(
  area = tea_areas,
  value = round(rnorm(9, mean = 120, sd = 25)),
  sd = round(runif(9, 3, 22), 1),
  geometry = grid
)

[推定値と不確実性のひとまとめ化]:duoコマンド

2つの数値ベクトルをまとめて1つのオブジェクトにし、二変量のマッピングであることが分かるクラスを付けます。geom_sfのfillにそのまま渡すと、以降のscale_fill_bivariate()やmanual_bivariate_scale()が値の組み合わせとして扱ってくれます。

オプション意味初期値
v11つ目の入力変数なし
v22つ目の入力変数なし
# 推定値と標準誤差をduo()でひとまとめにする
combined <- duo(tea$value, tea$sd)

# 返り値のクラスを確認する
class(combined)
[1] "bivariate" "list"

# どの変数を束ねたかを確認する
attr(combined, "vars")
[[1]]
tea$value

[[2]]
tea$sd

# duo()の結果をfillにそのまま渡して二変量マップを描く
ggplot(tea) +
  geom_sf(aes(fill = duo(value, sd)))

duo()の結果をfillにそのまま渡して二変量マップを描く

[二変量カラースケールの調整]:scale_fill_bivariateコマンド

duo()でまとめた2変数のマッピングに使う配色を調整します。基準となる色や配色コマンド、ビンの数を変えることで、2つの数値の組み合わせをどう色に落とし込むかを制御できます。

オプション意味初期値
…ggplot2::discrete_scale()に渡すその他のオプションなし
nameスケールの名前。凡例のタイトルに使う。waiver()だと最初のマッピングから取り、NULLだと凡例タイトルを省くwaiver()
var1_name凡例に使うv1の名前。NULLだとマッピングから取るNULL
var2_name凡例に使うv2の名前。NULLだとマッピングから取るNULL
colours配色の基準点となる色のベクトル。実際のパレットの作り方はbivar_palette()とbivar_fade_palette()を参照c(“#EDF8B1”, “#2C7FB8”)
palette_funcoloursとn_breaksを受け取り、全ビンの組み合わせに対応する色のベクトルを返すコマンド。NULLだとbivar_palette()を使うNULL
palette_paramspalette_funに渡す追加のオプションのリストlist()
n_breaks各変数に望むビンの数。整数か長さ2のベクトルで指定する。nice.breaks = TRUEだと目安として扱われ、実際のビン数は変わることがあるc(4, 4)
nice.breaks自動生成するビンの境界に、きりのよい読みやすい値を使うかどうかTRUE
quantile変数を分位点に基づくビンで区切るかどうか。分位点が重複する場合は等幅ビンになるFALSE
breaks2変数それぞれのビン境界を指定する長さ2のリスト。waiver()だとn_breaks、nice.breaks、quantileから自動計算するlist(waiver(), waiver())
labelsビン境界のラベルに使う文字列ベクトルかラベル付けコマンドの長さ2のリスト。waiver()だとbreaksから既定のラベルを作るlist(waiver(), waiver())
limits2変数それぞれの範囲を指定する長さ2のリスト。連続変数では含める数値範囲、離散変数では含める水準を指定するlist(NULL, NULL)
transformビン分けの前に連続変数へ適用する変換の長さ1または2のリストlist(“identity”, “identity”)
na.valuena.translate = TRUEのとき、欠損値をどの審美的属性値として表示するかNA
aestheticsこのスケールが対応する審美的属性の名前“fill”
guide凡例を作成するコマンドかその名前guide_bivariate()
# 既定の配色で二変量マップを描く
ggplot(tea) +
  geom_sf(aes(fill = duo(value, sd)))

# bivar_fade_paletteに差し替えて別の配色にする
ggplot(tea) +
  geom_sf(aes(fill = duo(value, sd))) +
  scale_fill_bivariate(
    palette_fun = bivar_fade_palette,
    colours = c("#F6E8C3", "orange", "red")
  )

# 収穫量と標準誤差でビンの数を変える
ggplot(tea) +
  geom_sf(aes(fill = duo(value, sd))) +
  scale_fill_bivariate(n_breaks = c(3, 4))

# 2変数とも等間隔の4ビンに区切る
ggplot(tea) +
  geom_sf(aes(fill = duo(value, sd))) +
  scale_fill_bivariate(
    n_breaks = 4,
    nice.breaks = FALSE
  )

既定の配色で二変量マップを描く

bivar_fade_paletteに差し替えて別の配色にする

収穫量と標準誤差でビンの数を変える

2変数とも等間隔の4ビンに区切る

[塗り色と輪郭色で2変数を表すデュアルマップ]:geom_sf_dualmapコマンド

各領域の塗り色と輪郭色に別々の変数を割り当て、1枚の地図で2つの数値を見せます。塗り色にduo()の結果を渡せば、塗り色自体も二変量の組み合わせとして表現できます。

オプション意味初期値
mappingaes()で作成した審美的属性のマッピングNULL
dataこのレイヤーで表示するデータNULL
…layer()に渡すその他のオプションなし
shapeグリフの形状。”circle”、”square”、”triangle”、”hex”、”drop”、”chernoff”のいずれかを指定する“circle”
max_angleangleの審美的属性を再スケーリングする際の最大値NULL
sizeグリフの大きさを調整する正の数値1
point_fun各領域の代表点を求めるコマンド。既定はsf::st_point_on_surface()sf::st_point_on_surface
border_colourグリフの輪郭線の色NA
na.rmFALSEのとき欠損値を警告付きで取り除くFALSE
show.legendこのレイヤーを凡例に含めるかどうかNA
inherit.aesFALSEのとき既定の審美的属性を上書きするTRUE
angle_guideangleの凡例を表示するかどうかTRUE
angle_nameangleの凡例に付けるタイトルwaiver()
angle_order他の凡例に対するangleの凡例の表示順2
fill_scale周囲の塗りに使うスケール。NULLだと、塗りのマッピングがduo()由来でない場合に既定の灰色のグラデーションを使うNULL
# 塗りと輪郭色をそれぞれ別の変数に割り当てたデュアルマップ
ggplot(tea) +
  geom_sf_dualmap(aes(fill = sd, colour = value))
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data

# 塗りをduo()による二変量スケールにし、輪郭色は対数変換した標準誤差にする
ggplot(tea) +
  geom_sf_dualmap(aes(fill = duo(value, sd), colour = log2(sd)))
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data

塗りと輪郭色をそれぞれ別の変数に割り当てたデュアルマップ

塗りをduo()による二変量スケールにし、輪郭色は対数変換した標準誤差にする

[代表点に図形を置くグリフマップ]:geom_sf_glyphコマンド

各領域の代表点に図形(グリフ)を置き、色と角度で2つの数値を表します。角度で表す変数はangleに、色で表す変数はcolourに割り当てます。

オプション意味初期値
mappingaes()で作成した審美的属性のマッピングNULL
dataこのレイヤーで表示するデータNULL
…layer()に渡すその他のオプションなし
shapeグリフの形状。”circle”、”square”、”triangle”、”hex”、”drop”、”chernoff”のいずれかを指定する“circle”
max_angleangleの審美的属性を再スケーリングする際の最大値NULL
sizeグリフの大きさを調整する正の数値1
point_fun各領域の代表点を求めるコマンド。既定はsf::st_point_on_surface()sf::st_point_on_surface
border_colourグリフの輪郭線の色NA
na.rmFALSEのとき欠損値を警告付きで取り除くFALSE
show.legendこのレイヤーを凡例に含めるかどうかNA
inherit.aesFALSEのとき既定の審美的属性を上書きするTRUE
angle_guideangleの凡例を表示するかどうかTRUE
angle_nameangleの凡例に付けるタイトルwaiver()
angle_order他の凡例に対するangleの凡例の表示順99
# 六角形のグリフで収穫量の推定値を色に割り当てる
ggplot(tea) +
  geom_sf_glyph(aes(colour = value), shape = "hex")
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data

# 標準誤差の大きさで向きを変えた雫型グリフ
ggplot(tea) +
  geom_sf_glyph(
    aes(colour = value, angle = sd),
    shape = "drop"
  )
Warning message:
st_point_on_surface assumes attributes are constant over geometries
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data

# ggChernoffパッケージが使える場合はChernoff顔グリフで表す
if (requireNamespace("ggChernoff", quietly = TRUE)) {
  ggplot(tea) +
    geom_sf_glyph(
      aes(colour = value, smile = sd),
      shape = "chernoff"
    )
}
Warning message:
st_point_on_surface may not give correct results for longitude/latitude data

六角形のグリフで収穫量の推定値を色に割り当てる

標準誤差の大きさで向きを変えた雫型グリフ

ggChernoffパッケージが使える場合はChernoff顔グリフで表す

[領域内にピクセルを敷き詰めるピクセルマップ]:geom_sf_pixelコマンド

各領域の中を格子状のピクセルで埋めます。塗り色にduo_pixel()の結果を渡すと、標準誤差が大きい地域ほど点のばらつきが視覚的に伝わります。幾何演算を高速にするため、事前に平面座標系へ変換しておきます。

オプション意味初期値
mappingaes()で作成した審美的属性のマッピングNULL
dataこのレイヤーで表示するデータNULL
nx方向とy方向のグリッド数。長さ1か2の整数で指定する60
distribution各領域内でピクセルの値を抽出する分布。”uniform”か”normal”を指定する“uniform”
seed再現性のための乱数の種NULL
pixel_shape生成するピクセルの形状。”hex”、”square”、”rect”のいずれか。”rect”はx方向とy方向を同じ区間数で分けるため長方形になることがある“hex”
flat_toppedTRUEだと上辺が平らな六角形、FALSEだと頂点が上を向く六角形にするFALSE
show.legendこのレイヤーを凡例に含めるかどうかNA
inherit.aesFALSEのとき既定の審美的属性を上書きするTRUE
…layer()に渡すその他のオプションなし
# 幾何演算を高速にするため、平面座標系(Webメルカトル)へ変換する
tea_flat <- sf::st_transform(tea, sf::st_crs(3857))

# 推定値と標準誤差をduo_pixel()でまとめ、六角形のピクセルで敷き詰める
ggplot(tea_flat, aes(fill = duo_pixel(value, sd))) +
  geom_sf_pixel(n = 25)

# ピクセルの形状と解像度を変える
ggplot(tea_flat, aes(fill = duo_pixel(value, sd))) +
  geom_sf_pixel(n = 15, pixel_shape = "square")

推定値と標準誤差をduo_pixel()でまとめ、六角形のピクセルで敷き詰める

ピクセルの形状と解像度を変える

[配色を手動で指定する二変量スケール]:manual_bivariate_scaleコマンド

自動生成の配色ではなく、ビンの組み合わせごとの色を自分で指定したいときに使います。valuesには、2変数のビン数の積と同じ数以上の色を、行優先で並べて渡します。

オプション意味初期値
aestheticsこのスケールが対応する審美的属性の名前なし
…ggplot2::discrete_scale()に渡すその他のオプションなし
values色を表す文字列ベクトル。長さはn_breaksの積以上必要で、2変数のビンの組み合わせごとに1色を対応させるなし
nameスケールの名前。凡例のタイトルに使う。waiver()だと最初のマッピングから取り、NULLだと凡例タイトルを省くwaiver()
breaks2変数それぞれのビン境界を指定する長さ2のリスト。waiver()だとn_breaks、nice.breaks、quantileから自動計算するlist(waiver(), waiver())
labelsビン境界のラベルに使う文字列ベクトルかラベル付けコマンドの長さ2のリスト。waiver()だとbreaksから既定のラベルを作るlist(waiver(), waiver())
limits2変数それぞれの範囲を指定する長さ2のリスト。連続変数では含める数値範囲、離散変数では含める水準を指定するlist(NULL, NULL)
transformビン分けの前に連続変数へ適用する変換の長さ1または2のリストlist(“identity”, “identity”)
na.valuena.translate = TRUEのとき、欠損値をどの審美的属性値として表示するかNA
na.translate離散スケールは既定で欠損値を表示する。表示したくない場合はna.translate = FALSEにするTRUE
drop未使用の因子水準をスケールから除くかどうか。TRUEだとデータに現れる水準のみ使うFALSE
guide凡例を作成するコマンドかその名前guide_bivariate()
n_breaks各変数に望むビンの数。整数か長さ2のベクトルで指定するc(4, 4)
quantile変数を分位点に基づくビンで区切るかどうか。分位点が重複する場合は等幅ビンになるFALSE
var1_name凡例に使うv1の名前。NULLだとマッピングから取るNULL
var2_name凡例に使うv2の名前。NULLだとマッピングから取るNULL
super構築するスケールに使う親クラスScaleBivariate
# 収穫量(緑の濃さ)と標準誤差(茶の濃さ)を掛け合わせた16色を手動で指定する
ggplot(tea, aes(fill = duo(value, sd))) +
  geom_sf() +
  manual_bivariate_scale(
    aesthetics = "fill",
    values = c(
      "#F7F4E9", "#D9CBA3", "#B99B5B", "#8C6D1F",
      "#DCEBD5", "#B7D9A8", "#8FBF7A", "#5E9C4A",
      "#B8DCE0", "#8FC4CB", "#5CA3AC", "#2E7A85",
      "#C9C2E0", "#A79BCB", "#8574B0", "#5F4A94"
    ),
    n_breaks = 4
  )

収穫量(緑の濃さ)と標準誤差(茶の濃さ)を掛け合わせた16色を手動で指定する


この記事が誰かの役に立ちますように。

スポンサーリンク
価格および配送状況は変更される場合があります。購入時は商品ページをご確認ください。
当サイトに表示されている商品情報はAmazonから提供されたものであり、更新または削除される場合があります。
karada-goodはAmazonアソシエイトとして、適格販売により収入を得ています。