cucumber flesh

Rを中心としたデータ分析・統計解析らへんの話題をしていくだけ

jpmeshバージョン1.2.0をリリース

統計調査などで使われる標準地域メッシュをRで扱うjpmeshパッケージのバージョン1.2.0 をCRANにリリースしました。以前のバージョンは1.1.3でした。マイナーアップデートですがいくつかの変更点・新機能がありますので紹介します。

f:id:u_ribo:20200328093427p:plain

インストール

2020年3月28日現在、WindowsおよびmacOSでのバイナリ版が用意されていない状況です。これらのOSを利用されている方はインストールをもうしばらくお待ちください。

install.packages("jpmesh") # v1.2.0
library(jpmesh)
library(sf)

メッシュサイズの指定を文字列から数値で行うように

これまでのjpmeshの関数では、メッシュサイズを指定する際に 80km のような文字列での指定が必要でした。

meshcode_set(mesh_size = "80km")

coords_to_mesh(141.3468, 43.06462, mesh_size = "500m")

rmesh(1, mesh_size = "1km")

これに対して、今回リリースされたv1.2.0では1kmを1として、すべてのメッシュサイズの指定を数値で行うように変更しました。すなわち、80kmのときは80、500mでは0.5、250mメッシュサイズの場合は0.25です。

上記のコードをv1.2.0で実行する際は以下のようにします。

meshcode_set(mesh_size = 80)

coords_to_mesh(141.3468, 43.06462, mesh_size = 0.5)

rmesh(1, mesh_size = 1)

メッシュサイズの変更 - mesh_convert()

次は追加した関数です。入力に与えたメッシュコードを適当なメッシュサイズに変更する mesh_convert() を用意しました。メッシュサイズのスケールアップ・スケールダウンが簡単に行えます。

set.seed(1)
rmesh(1) %>% 
  mesh_convert(to_mesh_size = 0.25)
##  [1] "4040745711" "4040745712" "4040745713" "4040745714" "4040745721"
##  [6] "4040745722" "4040745723" "4040745724" "4040745731" "4040745732"
## [11] "4040745733" "4040745734" "4040745741" "4040745742" "4040745743"
## [16] "4040745744"

スケールダウンの機能を持つ関数として fine_separate() がありますが、こちらは変換したいメッシュサイズにするまでに繰り返しの処理が必要になる場合がありました。

rmesh(1) %>% 
  fine_separate() %>% 
  purrr::map(fine_separate) %>% 
  purrr::reduce(c) %>% 
  unique()

mesh_convert()では 80km (80)から125m (0.125)までのメッシュサイズに対応しており、柔軟にメッシュサイズの変更ができます。

set.seed(2)
rmesh(1, mesh_size = 1) %>% 
  mesh_convert(to_mesh_size = 80)
## [1] "4931"

メッシュコードを変数に含むデータフレームのsf化 - meshcode_sf()

メッシュコードを含むデータフレームを処理することがあります。

set.seed(3)
df_mesh <- 
  tibble::tibble(
    meshcode = rmesh(1, mesh_size = 1) %>% 
      fine_separate(),
    value = rnorm(4))
df_mesh
## # A tibble: 4 x 2
##   meshcode   value
##   <chr>      <dbl>
## 1 492816651 -0.293
## 2 492816652  0.259
## 3 492816653 -1.15 
## 4 492816654  0.196

ここからメッシュコードのgeometry (polygon) を生成し、sfオブジェクトとして扱うための関数が meshcode_sf() です。引数 mesh_var にメッシュコードが記録されている変数名を与えて実行します。このとき、dplyrやtidyrで変数を指定するように引用符は必要ありません。

sf_mesh <- 
  df_mesh %>% 
  meshcode_sf(mesh_var = meshcode)
class(sf_mesh)
## [1] "sf"         "tbl_df"     "tbl"        "data.frame"
sf_mesh %>% 
  st_geometry() %>% 
  plot()

f:id:u_ribo:20200328092349p:plain

この機能は自分自身がよく使っていたものなので、実装できて満足しています。

次のリリースでは?

jpmeshは現在80kmメッシュから1kmメッシュまでの基準地域メッシュ、500m、250m、125mの分割地域メッシュに対応しています。国内で使われるメッシュコードには他に100mと50mの統合地域メッシュが存在します。これらについてサポートするかが議論されています。

github.com

100mメッシュが250mメッシュと同じ桁数になってしまうのでどうにかしないといけません。

また、対象のメッシュコードが人口集中地区(DID)をはじめとした国土政策関係の区域に含まれるかを判定する関数を実装予定でいます。

github.com

ご意見あるかたはGitHub もしくは Twitter (@u_ribo)まで。

スポンサーの検討もお願いいたします。

uribo.hatenablog.com

GitHub Sponsorsの募集を始めました、よろしくお願いします。

表題の通り、GitHub Sponsorsの審査を通過しましたので告知です。

要約

私のオープンソースソフトウェア(OSS)活動を支援するための寄付の受付を開始したので何卒一考ください。

f:id:u_ribo:20200327165250p:plain

きっかけ

GitHub Sponsorsは個人およびコミュニティのOSS活動を支援するための枠組みです。R界隈では世界の @Atsushi776 が始めたのが話題となりました(彼の告知記事。私もスポンサーになりました)。

私が得意とする言語はRです。学生時代から使っていて、まあ「ちょっとわかる」程度には使えると思っています。

Rはオープンソースで使うのにお金がかかりません。エディタとしても優秀な統合開発環境のRStudioアプリケーションも無料です。また、これまでに多くの書籍、プレゼンテーション、その他資料がインターネットで公開されてきました。

過去の人々の力に支えられている。その人たちは無償で行ってくれた。それなのに「お金儲け」をするのはどうなの?」という考えが少なからずあります。一方で仕事では前職から「ほぼR 100%」です。なので「お金稼ぎ」はしています。また書籍の執筆も少なからず行っており、それによる収入もあることも事実です。

ただ今年になって、そうした見方が変わってきました。Rは多くの研究、企業・業務でも使われる、素晴らしい言語です。そこには過去・現在・未来に豊富な人材があり、自分以上に生活の基盤としている人もいるでしょう(RStudio社はまさにそれ)。そして「技術はタダじゃない」そう思い至るようになりました。

自分の価値を低く見積もってはいけない。それはコミュニティ内の他のユーザや文化にも影響します。

なぜ支援を求めるのか

GitHub Sponsorsを始める前から、OSS活動を行う・幅を広げていく上でいくつかの課題がありました。それは次のようなものです。これらはいずれもお金で解決できる面があります。

  1. 英語力の向上
  2. 国際カンファレンス参加資金
  3. OSS参加のためのマシン、サーバ、サービス経費等 ... 現在の開発環境はiMac (2017) と MacBookPro (2013) がメインです。
  4. コミュニティ運営のモチベーション、活動経費
  5. R以外の言語、特にPython, Go, Juliaの学習

いくつかの項目について説明します。

OSS活動は、大別すると自分が開発者となり進めるもの、他の人・グループが中心にいる中で参画していくものがありますが、私はどちらかというと前者が中心で、グローバルなOSS活動についてはtypoの修正や簡単な機能実装等しか行えていないことが多く、まだまだ未熟さを感じています。そこには技術的な問題の他、「英語」の障壁が存在します(言語を問わず、コミュニケーション全般の課題でもありますが)。

言わずもがな、OSSでの中心言語は英語が主流です。1. 英語力の向上OSS活動を行う上で欠かせない能力だと捉えています。また次の2. 国際カンファレンス参加で他の開発者と交流する際も必要となります。

Rコミュニティには2つの大きな国際カンファレンスが毎年行われています。Rユーザの集会的なuseR!は、毎回開催箇所(国)が変わる面白さがあります。もう一つのRStudio conference (rstudio::conf) はRStudio社主催で本社のあるアメリカ開催です。

カンファレンスへの参加は先端の情報や意見交換ができるだけでなく、GitHubTwitterでお世話になっている人たちに会える絶好の機会です!一方でいずれも海外の開催&一週間ほどの滞在で個人で気軽に行くのには現実的な問題があります。(所属する企業でサポートがあると良いのですが、私の所属組織ではそうは行きません)

最後に4. コミュニティ運営のモチベーション、活動経費です。コミュニティを維持するためには時間もお金もかかります。私はTokyo.RおよびTsukuba.Rの2つのコミュニティに関わっています。と言っても、どちらもほとんど貢献できていません。

Tokyo.Rの方は運営メンバーではありませんが、Slackコミュニティのr-wakalangの保守とRユーザと話すpodcastR Radio for the Rest of us (R3)を継続しています。

また茨城県つくば市周辺のRユーザを対象にしたTsukuba.Rも再起動したものの、定期的に行える体制が整っていません。これは会場の確保をはじめとした各種の手続きに手間取ることが原因の一つです。コミュニティの形成は一朝一夕には行きませんが、ユーザを育てるためには欠かせないものだと信じています。私の怠惰で行えていないことは大いに反省すべきでしょう。一方でこれらの活動は完全に自らの時間と金を使って行われています。私のOSS活動の最終地点は、未来のためのユーザの育成(あるいは財産の共有)だと考えています。培った技術、情報は次世代に残していきたいです。

こんなことをしています

  • Rパッケージ開発
    • CRANに登録されているもの(jpmesh ⭐️26, zipangu ⭐️21, jpndistrict ⭐️11 fgdr ⭐️5)
    • 時々 rstudio関係、rOpenSci、r-spatialのパッケージへissueやPRを出します
  • 資料公開 (執筆、スライド、ブログ)
    • このブログQiitaの記事で使ったコードはリポジトリでも公開しています。またTokyo.Rをはじめとしたイベントでの講演資料もSpeakerdeckと共にアップロードしています。
    • 更新をサボりがちですが、空間解析や機械学習のための執筆をしています。

uribo.github.io

github.com

  • 可視化プロジェクト ... あれこれとやっています。地図を使ったものが多いです。可能な限りコードを公開しています。

f:id:u_ribo:20200327165449p:plain

  • 情報発信 ... 毎日GitHubに張り付いているので、新しいパッケージや機能追加は比較的早い段階でキャッチアップしています。スポンサーに情報共有するというのはアリかもしれません。

speakerdeck.com

speakerdeck.com

サポートする意思のある人へ

ここまであれこれと宣伝でした。ではいよいよスポンサー枠のご案内です。現在5つの枠を用意していますが、

  • $3/month または $6/monthは個人枠
  • $20/month, $50, $1000 ($100ではない)を企業枠と捉えています(もちろん個人でやってくれても大歓迎)

の2つが大きくあります。月単位でのサポートも可能です。その場合、サポートを停止するのをお忘れなく。

また、スポンサーになっていただけるのはどなたでも歓迎ですが、次の条件に合っているかどうか、踏みとどまって欲しい項目をあげておきます。

  • 私の開発するRパッケージ、資料を活用している人
  • 私を通じてコミュニティ活動を支えたい人
  • 私自身を応援したい人

スポンサーへの直接のお礼や特典は今のところありませんが、感謝の気持ちは述べさせてください。加えて、支援してくれる理由やお金の用途の指定があれば教えていただけますと幸いです。

それでは、瓜生真也と未来のRコミュニティのためにどうぞよろしくお願いします。

github.com

parzerパッケージで多様な緯度経度の表記を十進数に変換する

信頼と実績のrOpenSciから新しいパッケージがCRANに登録されました。parzerパッケージです。 このパッケージは多種多様な緯度経度の表記形式を処理し、十進数での表記(DEG: Degree)に変換してくれるものです。 (例えば「139°44’28.8869」を「139.7414」にする)

CRANリリース情報および基本的な関数の紹介はrOpenSciのブログ知りました。ぜひこちらもご覧ください。

ropensci.org

また、私自身も以前に同様の処理を行う方法としてこのような記事を書いています。 ですがparzerパッケージを使うとより簡単に緯度経度座標の表記を修正できます。 日本語の表記を扱う際には課題が残っているので、その対策を後述します。

まずは基本的な使い方を見ていきましょう。

install.packages("parzer")
library(parzer)

パース関数

入力された座標の値を十進数での表記に修正するパース関数はparse_*()で整備されています。 parse_lat()parse_lon()はそれぞれlatitude(緯度)、longitude(経度)を処理します。

日本経緯度原点の座標を例にします。

x <-  "E139°44’28.8869"
y <- "N35°39’29.1572"

parse_lon(x)
## [1] 139.7414
parse_lat(y)
## [1] 35.6581

パースした結果をマップ上で確認します。せっかくなので国土地理院地理院タイルを背景に。

library(sf)
library(leaflet)
library(sfheaders)
basemap <- 
  leaflet() %>%
  addTiles("http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
           attribution = "<a href='http://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>")

sfheaders::sf_point(st_point(c(parse_lon(x), 
                               parse_lat(y)))) %>% 
  st_set_crs(value = 6668) %>% 
  st_transform(crs = 4326) %>% 
  mapview::mapview(map = basemap)

f:id:u_ribo:20200321130422j:plain

しっかりと「日本経緯度原点」にポイントが落ちていますね。

parse_*()は多様な表現方法に対応しています。

coords <- c(45.23323, "40:25:6N", "40°25’5.994N")
parse_lat(coords)
## [1] 45.23323 40.41833 40.41833

parse_lon_lat()は二つの引数に同じ長さの経度、緯度のベクトルを与えてデータフレーム形式で結果を返却します。

df <- 
  data.frame(
    lon = x,
    lat = y,
    stringsAsFactors = FALSE)

parse_lon_lat(df$lon, df$lat)
##   lon lat
## 1 139  35

また度分秒の要素を分解する関数として pz_*()があります。以下の例で度分秒それぞれの要素に分解します。

pz_degree(x)
## [1] 139

pz_minute(x)
## [1] 44

pz_second(x)
## [1] 28.90863

日本語での度分秒の処理

現在のバージョン(v0.1.0)ではUnicodeを扱う際には課題があります。

https://github.com/ropensci/parzer/issues/10 github.com

具体的には次のように日本語での「東経」「北緯」、「度分秒」を扱う際に発生する問題です。

x <- "東経139度44分28秒8869"
y <- "北緯35度39分29秒1572"

x %>% 
  parse_lon()
##  [1] NaN
y %>% 
  parse_lat()
##  [1] NaN

うまくパースされません。これに対して簡単な方法ですが、「度」「分」「秒」を変換しておきます。そうすると正常にパースできます。

@Atsushi776 さんに効率的な置換の方法を教えてもらったので書き直しています👇

library(stringr)
x_res <- 
  x %>% 
  str_replace("東経", "E") %>% 
  str_replace_all(c("度" = "\u00b0", "分" = "\u2019", "秒" = "."))
x_res
## [1] "E139°44’28.8869"
parse_lon(x_res)
## [1] 139.7414

y %>% 
  str_replace("北緯", "N") %>% 
  str_replace_all(c("度" = "\u00b0", "分" = "\u2019", "秒" = ".")) %>% 
  parse_lat()
## [1] 35.6581

さらに関数化するなら以下のような感じで。

replace_dohunbyo_kanji <- function(x) {
  str_replace_all(x, c("東経" = "E", "西経" = "W",
                    "北緯" = "N", "南緯" = "S"), 
               c("E", "W",
                 "N", "S")) %>% 
    str_replace_all(c("度" = "\u00b0", "分" = "\u2019", "秒" = "."))
}

replace_dohunbyo_kanji(x)
## [1] "E139°44’28.8869"

replace_dohunbyo_kanji(y) %>% 
  parse_lat()
## [1] 35.6581

Enjoy!