自治体一覧

全国の自治体一覧は国税庁の法人番号公表サイトの市町村にあるcities.xlsxに列挙されている。

library(readxl)
cities = read_excel("cities.xlsx", skip=1)
dim(cities)
[1] 1718    4

1718自治体がリストされている。

ただ,この表には郵便番号がない。そこで,郵便局の事業所の個別郵便番号データダウンロードから最新データのダウンロード(ZIP)を取ってきて展開すると JIGYOSYO.CSV というCSVファイルが得られる。

JIGYOSYO = read.csv("JIGYOSYO.CSV", header=FALSE, fileEncoding="CP932", as.is=TRUE)
x = JIGYOSYO[grep("(市役所|町役場|村役場)$", JIGYOSYO$V3), 3:8]
dim(x)
[1] 1371    6

1371自治体しか個別郵便番号を持っていない。ということで,少し考え直す。

まず国税庁の1718自治体について,自治体名がユニークかどうか調べてみる。

c = cities$名称
u = unique(c)
n = sapply(u, function(x) sum(c == x))
table(n)
n
   1    2    3    4 
1659   20    5    1 
c[n == 4]
[1] "池田町"
subset(cities, 名称=="池田町")
         法人番号   名称                                   所在地 備考
163 1000020016446 池田町       北海道中川郡池田町字西1条7-11   NA
774 2000020183822 池田町           福井県今立郡池田町稲荷35-4   NA
871 9000020204811 池田町 長野県北安曇郡池田町大字池田3203-6   NA
916 8000020214043 池田町     岐阜県揖斐郡池田町六之井1468-1   NA

都道府県名を取得するところでリストのバグに気づいた。木更津市と日置市だけ県名がない。

pref = substr(cities[,3], 1, regexpr("..(都|道|府|県|市)", cities[,3], perl=TRUE)+2)
pref[pref == "木更津市"] = "千葉県"
pref[pref == "日置市"] = "鹿児島県"

都道府県名を合わせれば自治体名はユニークになる:

cp = paste0(cities[,2], " ", pref)
length(cp)
[1] 1718
length(unique(cp))
[1] 1718

郵便番号表からはユニークなものが1354役場ある。これも都道府県を付けてユニークにする。

length(unique(x$V3))
[1] 1354
xp = paste0(x$V3, " ", x$V4)
length(xp)
[1] 1371
length(unique(xp))
[1] 1369
uxp = unique(xp)
nuxp = sapply(uxp, function(x) sum(xp == x))
table(nuxp)
nuxp
   1    2 
1367    2 
uxp[nuxp == 2]
[1] "八幡平市役所 岩手県" "青梅市役所 東京都"  

青梅市役所は単なるダブりみたい。八幡平市役所は本当に2箇所あるのか?

国税庁データのほうにも「役所」または「役場」を追加する。

cc = ifelse(grepl("市$", c), paste0(c, "役所"), paste0(c, "役場"))
ccp = paste0(cc, " ", pref)
length(ccp)
[1] 1718
length(unique(ccp))
[1] 1718
setdiff(uxp, ccp)
 [1] "鯵ケ沢町役場 青森県"           "七ヶ宿町役場 宮城県"          
 [3] "茨城県 鉾田市役所 茨城県"     "牧村役場 新潟県"              
 [5] "岐阜県加茂郡富加町役場 岐阜県" "一色町役場 愛知県"            
 [7] "吉良町役場 愛知県"             "幡豆町役場 愛知県"            
 [9] "愛知県大府市役所 愛知県"       "愛知県 高浜市役所 愛知県"    
[11] "海部郡大治町役場 愛知県"       "愛知県知多郡東浦町役場 愛知県"
[13] "滋賀県 守山市役所 滋賀県"     "大阪府 大東市役所 大阪府"    
[15] "大阪府泉南市役所 大阪府"       "鳥取県 境港市役所 鳥取県"    
[17] "東出雲町役場 島根県"           "広島県安芸郡坂町役場 広島県"  
[19] "香川県 善通寺市役所 香川県"   "須惠町役場 福岡県"            
length(setdiff(ccp, uxp))
[1] 369

これでだいたい構造がわかったので,国税庁データについて郵便番号(zip)を求める:

zip = sapply(1:1718, function(i) x[grep(ccp[i], xp)[1], 6])
length(zip)
[1] 1718
sum(!is.na(zip))
[1] 1364

これで1718件中1364件は郵便番号が求められた。残り354件はおそらく個別郵便番号がないのであろう。

一般の郵便番号データはこちら全国一括をダウンロードすればよい。展開してでてくるCSVファイルを読む:

yuubin = read.csv("KEN_ALL.CSV", header=FALSE, fileEncoding="CP932")

V7〜V9が住所,V3が郵便番号である。税務署データの住所 cities[,3] が一番近いものを選べばよい。

コピペのチェックでも書いた編集距離を使ってみる。

library(stringdist)
addr = paste0(yuubin[,7], yuubin[,8], yuubin[,9])
dist = rep(NA, 1718)
for (i in 1:1718) {
  if (is.na(zip[i])) {
    d = stringdist(cities[i,3], addr, method='lv')
    m = min(d)
    zip[i] = yuubin[d == m, 3][1]
    dist[i] = m
  }
}

これでとりあえず埋めることができた。

cities$zip = zip
cities$dist = dist
write.csv(cities, "cities_zip.csv", quote=FALSE, eol="\r\n", row.names=FALSE, fileEncoding="CP932")

試行錯誤の列挙になってしまった。もっと良い方法を緩募。

なお,上の自治体数は特別区を含んでいない(含めるべきだったのだろう)。

なお,郵便番号付きの自治体一覧はJ-LISの地方公共団体コード住所からたどれるページにあるので,こちらをスクレーピングしたほうが早いかもしれない。

総務省にも全国地方公共団体コードがあるが,こちらは住所や郵便番号はない。