zipangu日本人が頻繁に遭遇するデータ操作を効率的に行うための{zipangu}パッケージ、想定よりも多くの人が喜んでくれたようで、私としても嬉しく思っています。記事の最後にプロジェクトの協力者を募集したら数名からの反応があり、また新機能の要望も挙げられました。ありがとうございます。次のリリースでは郵便番号の処理を効率的に行う機能を実装する計画でいます。具体的には日本郵便が提供する郵便番号csvファイル(以下、郵便番号データ)をRで読み込む関数と、郵便番号の検索および住所情報を返却する機能です。GitHubファイルの読み込みに関してはすでにmasterブランチへマージされています。郵便番号検索の方もここで読み込んだファイルを利用すれば良かろうと思っていたのですが、こんなご意見をいただきました。2019年12月10日どうもこの郵便番号データには問題があるそうです。郵便番号データを読み込むための関数です。is_cyoumoku)例えば郵便番号066-0005のレコードを検索すると次のように3件のデータが返却されます。同じ郵便番号、市町村なのになぜ?となりますが、street列で表示している町域名がおかしいことに気がつきます。0なんと、これは郵便番号データ番号ファイルの仕様です。データの説明書きに次の記述があります。全角となっている町域部分の文字数が38文字を越える場合、また半角となっているフリガナ部分の文字数が76文字を越える場合は、複数レコードに分割していますこのままでは検索用の関数を用意する際に問題になります。これ以外にも数々の問題点があり、これまでに多くの方が記事にまとめてくださっています。この行の分割をはじめとしていくつかの問題への対策方法が書かれている記事も見受けられました。bleis-tift.hatenablog.comtogetter.com一方で、次の2点に関する具体的な処理方法については見つけることができませんでした。独立させる以下に示すように、元のデータはtidy1ではありません。扱うデータがtidyであることを心がける身としては放っては置けない問題です。大通西2丁目そんなわけで前置きが長くなりましたが、こうした問題の解決に取り組んでいます。いくつかの課題に関しては解決できそうと目処が立つ、一方で完璧には程遠いことを感じてきたので一旦整理しておきます。住所の重複と複数行に分割される問題には、これまでに書かれている記事を参考に次の関数を用意することで対処しました。関数のコードはGitHubに置いてますので興味のある人は見てください。読み込んだ郵便番号データに次の関数を適用することで同一住所の行に正しく住所が格納されるようになります(複数行の先頭と終了の行番号を特定し、その間の町域名を結合するだけ)。zip_tidy_prep()まずは住所の重複の確認から。2つの値を持っているのですが、単純に郵便番号と住所を紐付ける目的であればユニークに扱ってしまうのが良いです。一行ずつのデータになっていますね。続いて、複数行にまたがって記録される町域名です。"協和(88−2、271−10、343−2、404−1、427−5、1137−3、1392、1657、1752番地)"ここまでは難なくでした。ここからが闇のゲームの始まりです。「、」で区切られた住所を分割する冒頭にあげたように、tidyデータの理念に基づくと町域名の「、」ごとに行を分けるのが妥当な処理です。これをやってみましょう。str_split()で「、」の位置で要素を分解します。"1752番地)"要素に分解できたものの、次は共通の住所文字列をつけたり(ここでは先頭および末尾に「協和」と「番地」を与えることになります)、余分な括弧を取り除く作業が残ります。それを行う関数も書きました。"協和1752番地"他のデータでも見てみましょう。今度は末尾に「番地」がつかない例です。"天王長沼"これをデータフレームに適用します。京都市内で伝統的に使われる住所の表記形式として「通り名」があります。「上る」や「東入」などがつくやつ。Wikipediaこの表記は当然郵便番号データにも記録されています。裏寺町通四条上る)"ここでは表記上では「中之町」が末尾に来るようにしなくてはいけません。マピオンのウェブページではキチンんと処理されています。そのため、先ほどの処理を適用すると次のようになるのでダメです。そこで京都市内で使われる通り名かを判定する関数を用意し、通り名の住所であれば「中之町」のような街名を末尾に移動させるようにしました。"裏寺町通四条上る中之町"これで単純なパターンであれば対応可能となりました。次に待ち構えるのは中ボスです。実は先ほどのsplit_inside_address()が対応できる括弧内の文字列の処理は、括弧が一つの場合のみです。次のように丸括弧と鉤括弧が使われていると正しく処理できません。"葛巻176を除く」〜第45地割"これについては「鉤括弧内の『、』については区切り文字のルールから除外する」正規表現を書けば良いのですが、私の技術力不足でできていません。したデータの件数は9つと少ないので、今の所は該当データを発見したら鉤括弧以外の「、」を「_」に変更し、共通名称をつけた名前に変換する処理を取っています。"葛巻第40地割「57番地125、176を除く」_葛巻第41地割_葛巻第42地割_葛巻第43地割_葛巻第44地割_葛巻第45地割"これによりtidyr::separate_rows()の行方向への分割が適用可能となります。rows「〜」によって省略される住所を復元する郵便番号データをtidyにするための2つ目の条件です。一度問題を確認しておきましょう。"大通西(1〜19丁目)"ここでの「大通西(1〜19丁目)」は「〜」によって省略されています。我々にはこの中に「大通西2丁目」や「大通西18丁目」が含まれていることが推測できますがコンピュータに識別させるのは簡単ではありません。「大通西2丁目」で検索した時にコンピュータこの住所を見つけてもらうための簡単な方法は省略された数値を用意してあげることです。そこで、「〜」によって省略される数値の最小値と最大値の範囲に含まれる数値を住所文字列と組み合わせて復元する以下の関数を用意しました。"大通西19丁目"区切りが2つだけ、つまり「〜」ではなく「、」で分割される時はこうします。prefixとsuffix引数を用意することで柔軟な住所文字列を作ることが可能となりました。"吾妻2丁目"こうしたデータは多数あり、「丁目」を含むものの他「番地」「線」が使われるものなどバリエーションに富んでいます。rowid)多様なパターンに対応するため、次のようなコードを書きました、がまだ途中です。rows残った課題ここまで、悪名高い郵便番号データと戦ってきましたが、現在相手にリードされた状況です...。いくつかの課題については対策できたと思いますがまだ満足できていません。具体的には以下の3点をどうにかしないといけません。正規表現がもう少し綺麗に書けると良いのですが。「以外」、「を除く」、「その他」などのアンチパターン存在しない住所を除く特に3つめ「存在しない住所を除く」は手を焼きそうです。最後の処理として「〜」で省略された住所を復元しましたが一方で現実には存在しない住所を生み出してしまった可能性があります。「58番地」は存在しますが、それより小さな「50番地」は存在しません。センターのジオコーディングサービスにも含まれません。"60"未完の状態で終わるため俺たたエンドです。これらの問題を解決できた時にまたお会いしましょう!アドバイスがあればください。俺たちの戦いはこれからだ!効果的なデータ分析を行いやすくするためのデータの持ち方を指す概念。10:24郵便番号データをtidyにする挑戦Tweet広告を非表示にする関連記事2019-12-02住所や年号、漢数字のデータ操作を楽にするRパッケージをCRANに登録しました副題「失われた『Nippon』を求めて」(仰々しい)。(1)はてなブログをはじめよう!u_riboさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。