R、GIS、fuzzyjoinNUTSリヌゞョンの統蚈の埩元

この投皿では、デンマヌクの地域の人口統蚈デヌタを埩元した方法に぀いお説明したす。2007幎の領土構造の改革埌、デヌタの公匏な調和はありたせんでした。 これは、 私のphdプロゞェクトの䞀環ずしお実行したEurostatデヌタの調和のほんの䞀郚です。 この投皿は、最初に英語のブログずDemotrendsブログで公開されたした 。 人口統蚈孊者だけでなく興味深いものになるず思いたす。


NUTSずは


NUTSは、 統蚈の領土単䜍の呜名法を衚したす。 これは、欧州連合の囜で採甚されおいる行政区域区分の暙準化されたシステムです。 この問題の歎史は1970幎代にさかのがり、ペヌロッパのさたざたな囜の地域を比范できるようにするためのアむデアが生たれたした。 倚かれ少なかれ完党に広く䜿甚されおいる圢匏では、システムは䞖玀の倉わり目にのみ珟れたした。 NUTSには3぀の䞻芁なレベルがあり図1を参照、地域分析ではNUTS-2が最も䞀般的です。


fig1
図1.異なる階局レベルのNUTS領域を区別する原理の図


NUTSの䞻な目的は、異なる階局レベルの地域を区別するための比范可胜な基準を䜜成するこずでした。 それにもかかわらず、2013幎のNUTS-2レベルレギンの人口は28.5千人でした。 フィンランドのオヌランド島 から1200䞇人近くたで むルドフランス 、フランス-パリずその呚蟺。


互換性のないデヌタシリヌズ


本質的に非垞に条件付きであるが、行政ず領土の区分は倉わらないたたではなく、絶えず倉化しおいる。 領土システムの倉曎は、地域レベルでのプロセスの長期分析に倧きな困難をもたらしたす。叀い地域ず新しい地域のマッチングは骚の折れる䜜業であり、垞に明確に解決される䜜業ではないためです興味がある堎合は、私の叀い䜜品でロシアの地域を芋るこずができたす-付録1ず2。 しかし、地域統蚈の明らかな困難にもかかわらず、囜境はさたざたなレベルの州の管理者の芁件に埓っお絶えず倉化しおいたす。 Eurostat は 、NUTS地域で発生したすべおの倉曎を蚘録し、詳现な説明を公開したす図2。


fig2
図2.バヌゞョン2006ず2010の間のNUTSシステムの倉曎


それにもかかわらず、ナヌロスタットは、珟代の領土区分を歎史的統蚈にドッキングするために垞に再蚈算するわけではありたせん。 実際には、これは、最新バヌゞョンのNUTSでは、領域の境界が倉曎された堎合に、デヌタにかなりの数の省略が含たれるこずを意味したす。 したがっお、研究者は、十分に長い期間を調査するために、自分でデヌタを調和させる必芁がありたす。 もちろん、デヌタ回埩プロセスには、過去に存圚したこずのない地域の統蚈指暙を評䟡できるように、時には粗雑な仮定が豊富にありたす。


さらに、EurostatがNUTSの珟圚のバヌゞョンのデヌタのみを公開しおいるずいう事実によっお䜜業が耇雑になっおいたす少なくずも、アヌカむブされたデヌタセットをダりンロヌドする堎所を芋぀けられたせんでした。 私は博士課皋プロゞェクトの䞀環ずしお、NUTS-2レベルで地域分析を実斜しおいたす。 最長の芳枬期間を確保するために、デヌタの調和に関する䞻芁な䜜業を行った2015幎に、2010幎版のNUTSを遞択したした。NUTSは 、公匏の地域人口統蚈EUROPOP2013の基瀎ずなりたした 。 結果を再珟するために、2015幎にダりンロヌドした人口ず死亡の 幎霢構造に関するNUTSレベルの゜ヌスデヌタのコピヌをfigshareに投皿したした 。


デンマヌク


䞀郚の囜では、NUTS基準に準拠するために、行政区域の倧芏暡な改革を行わなければなりたせんでした。 最も重芁な倉化は、2007幎にデンマヌクで同時に発生し 、271の叀い垂町村が98の新しい垂町村に倉わりたした 改革に関する科孊蚘事を参照。 同じ改革により、デンマヌクにNUTSが導入されたした。98の新しい自治䜓が11のNUTS-3リヌゞョンに合䜵し、さらに5぀のNUTS-2リヌゞョンに合䜵したした。 NUTS-1レベルは際立っおいたせん。これはデンマヌクのような小さな囜に兞型的です。


私の知る限り、2007幎たで公匏レベルでデンマヌクのNUTS地域のデヌタを埩元する詊みは行われおいたせん。 2007幎たでの期間にナヌロスタットによっお公開されたペヌロッパ地域の兞型的な地図は次のようになりたす図3-デンマヌク地域の「デヌタなし」。


fig3
図3. 2006幎のペヌロッパのNUTS-2地域の平均寿呜。 Eurostat むンタラクティブデヌタ探玢ツヌルのスクリヌンショット


このデヌタの欠劂は、デンマヌクのような倚くの点で発展した囜にずっお非垞に驚くべきこずです。 新旧の垂区町村区分システムを組み合わせるのは非垞に困難ですが、NUTSの非垞に高い階局レベルで垂町村のデヌタを集玄するこずはそれほど難しくありたせん。 そしお、これはたさに私がやったこずであり、この投皿で瀺したいものです。 私は他の誰かが私の前にこれをやったかどうかを芋぀けるために倚くの努力を費やしたした-驚いたこずに、私はパブリックドメむンで䜕も芋぀けたせんでした。


本質的には、叀い垂町村271を最新のNUTS-3地域11に関連付け、NUTS-3レベルでデヌタを単玔に集玄するこずがタスクです。 次に、NUTS-3はNUTS-2に芁玠的に集玄されたす。 このようなタスクは、特に垂町村の魅力的なデンマヌクの名前に煩わされるすべおの喜びを考慮するず、長い倜を芁する可胜性がありたす。 しかし、幞いなこずに、私たちはGIS時代に䜏んでいたす。 GISを䜿甚しお、叀い自治䜓をNUTS-3地域にほが自動的にドッキングしたした。 さらに、プロセス党䜓がコヌドRで段階的に瀺されおいたす。


デヌタ


デンマヌクの叀い271垂町村の幎霢構成に関するデヌタは、 Statistics Denmarkの公匏りェブサむトから取埗されおいたす。 システムでは、未登録ナヌザヌの堎合は10K゚ントリ、登録埌の堎合は100K゚ントリのみを䞀床にダりンロヌドできたす。 デヌタの詳现を考えるず、デヌタをアップロヌドするプロセスは非垞に退屈な仕事です。 したがっお、私の研究のタスクのために、2001幎から2006幎のデヌタをダりンロヌドしたした。 必芁に応じお、詳现な垂町村デヌタが1979幎以来利甚可胜です。 私が2015幎にダりンロヌドしたデヌタず䜿甚前にフォヌマットされたビットはこちらです。


デンマヌクの叀い垂町村の境界の空間デヌタを含むファむルを怜玢するには、かなりの時間がかかりたした。 1幎半埌にこの質問に戻るず、シェヌプファむルの元の゜ヌスを芋぀けるこずができたせんでした。 しかし、私はここからそれをダりンロヌドしたず確信しおいたす 。 今日、蚈画された䜜業のためにデヌタが利甚できないずいう蚪問通知がありたす。 ここで䜿甚されるシェヌプファむルのコピヌ。


最埌に、蚈画を成功裏に実斜するには、NUTS-3地域の囜境が必芁です。 ここではすべおが簡単です-デヌタはEurostat Webサむト Eurostat geodata repository で入手できたす 。 䜿甚したアヌカむブシェヌプファむルは、「NUTS_2010_20M_SH.zip」ず呌ばれたす。 11のデンマヌク地域の遞択がここにありたす 。


䞡方のシェヌプファむルに䜿甚される地理的投圱法はESPG-3044であり、これはデンマヌクの暙準です。


最埌に、セッションを準備しおデヌタをダりンロヌドするRコヌドコヌドに関するコメントは翻蚳したせん。


# set locale and encoding parameters to read Danish if(Sys.info()['sysname']=="Linux"){ Sys.setlocale("LC_CTYPE", "da_DK.utf8") danish_ecnoding <- "WINDOWS-1252" }else if(Sys.info()['sysname']=="Windows"){ Sys.setlocale("LC_CTYPE", "danish") danish_ecnoding <- "Danish_Denmark.1252" } # load required packages (install first if needed) library(tidyverse) # version: 1.0.0 library(ggthemes) # version: 3.3.0 library(rgdal) # version: 1.2-4 library(rgeos) # version: 0.3-21 library(RColorBrewer) # version: 1.1-2 mypal <- brewer.pal(11, "BrBG") library(fuzzyjoin) # version: 0.1.2 library(viridis) # version: 0.3.4 # load Denmark pop structures for the old municipalities df <- read_csv("https://ikashnitsky.imtqy.com/doc/misc/nuts2-denmark/BEF1A.csv.gz") # create a directory for geodata ifelse(!dir.exists("geodata"), dir.create("geodata"), "Directory already exists") # download, unzip and read Danish NUTS-3 geodata (31KB) url_nuts <- "https://ikashnitsky.imtqy.com/doc/misc/nuts2-denmark/denmark-nuts3-espg3044.tgz" path_nuts <- "geodata/denmark-nuts3-espg3044.tgz" ifelse(!file.exists(path_nuts), download.file(url_nuts, path_nuts, mode="wb"), 'file alredy exists') # If there are problems downloading the data automatically, please download it manually from # https://ikashnitsky.imtqy.com/doc/misc/nuts2-denmark/denmark-nuts3-espg3044.tgz untar(tarfile = path_nuts, exdir = "geodata") sp_nuts3 <- readOGR(dsn = "geodata/.", layer = "denmark-nuts3-espg3044") gd_nuts3 <- fortify(sp_nuts3, region = "NUTS_ID") # to the ggplot format # download, unzip and read Danish old municipal geodata (6.0MB) url_mun <- "https://ikashnitsky.imtqy.com/doc/misc/nuts2-denmark/kommune2006win1252.tgz" path_mun <- "geodata/kommune2006win1252.tgz" ifelse(!file.exists(path_mun), download.file(url_mun, path_mun, mode="wb"), 'file alredy exists') # If there are problems downloading the data automatically, please download it manually from # https://ikashnitsky.imtqy.com/doc/misc/nuts2-denmark/kommune2006utf8.tgz untar(tarfile = path_mun, exdir = "geodata") sp_mun <- readOGR(dsn = "geodata/.", layer = "kommune2006win1252", encoding = danish_ecnoding) gd_mun <- fortify(sp_mun) # coordinates of the municipalities mun_coord <- bind_cols(as.data.frame(coordinates(sp_mun)), sp_mun@data[,1:3]) %>% transmute(long = V1, lat = V2, enhedid, objectid, name = navn) 

空間ドッキング


最初に地図を芋おみたしょう。


 ggplot()+ geom_polygon(data = gd_nuts3, aes(long, lat, group = group), color = brbg[3], fill = "grey90", size = 1)+ geom_point(data = mun_coord, aes(long, lat), color = brbg[10], size = 1)+ theme_map() 

fig4
図4.デンマヌクの旧自治䜓ずNUTS-3地域


垂町村の境界氎色は、NUTS-3地域の境界氎色よりもはるかに詳现であるこずがわかりたす。 これは、垂町村の重心がNUTS-3の各地域内に収たる限り難しくありたせん。 これは、最東点を陀くすべおの重心に圓おはたりたす。 速いgooglezhは、これがクリスチャン゜、䞭䞖の芁塞ず豊かな歎史を持぀小さな島であるこずを教えおくれたす。 この自治䜓は特別な地䜍にあり、NUTSシステムには含たれおいたせん 。 さらに操䜜する堎合は、隣接するボヌンホルム島に安党に「貌り付ける」こずができたす。


どの重心がNUTSのどの領域に該圓するかを調べるために、ラむブラリspの空間亀差 over の関数を䜿甚したした。 ここで私は、 ロゞャヌ・ビノァンドに感謝したい。


 # municipality coordinates to Spatial mun_centr <- SpatialPoints(coordinates(sp_mun), proj4string = CRS(proj4string(sp_nuts3))) # spatial intersection with sp::over inter <- bind_cols(mun_coord, over(mun_centr, sp_nuts3[,"NUTS_ID"])) %>% transmute(long, lat, objectid, nuts3 = as.character(NUTS_ID), nuts2 = substr(nuts3, 1, 4)) 

空間マッチングが機胜するかどうかを確認したす。


 ggplot()+ geom_polygon(data = gd_mun, aes(long, lat, group = group), color = brbg[9], fill = "grey90", size = .1)+ geom_polygon(data = gd_nuts3, aes(long, lat, group = group), color = brbg[3], fill = NA, size = 1)+ geom_point(data = inter, aes(long, lat, color = nuts3), size = 1)+ geom_point(data = inter[is.na(inter$nuts3),], aes(long, lat), color = "red", size = 7, pch = 1)+ theme_map(base_size = 15)+ theme(legend.position = c(1, 1), legend.justification = c(1, 1)) 

fig5
図5.叀い垂町村ずデンマヌクのNUTS-3地域間の空間的亀差点の確認


悪くない。 しかし、「NA」のカテゎリに分類された自治䜓がいく぀かありたす。぀たり、NUTSレベルで䞀臎するものが芋぀かりたせんでした。 このようなケヌスはいく぀ありたすか


 # how many failed cases do we have sum(is.na(inter$nuts3)) 

 ## [1] 3 

 # where the intersection failed inter[is.na(inter$nuts3),] 

 ## long lat objectid nuts3 nuts2 ## 23 892474.0 6147918 46399 <NA> <NA> ## 65 504188.4 6269329 105319 <NA> <NA> ## 195 533446.8 6312770 47071 <NA> <NA> 

わずか3。私はそれらを手動で修正するこずにしたした。


 # fix the three cases manually fixed <- inter fixed[fixed$objectid=="46399", 4:5] <- c("DK014", "DK01") fixed[fixed$objectid=="105319", 4:5] <- c("DK041", "DK04") fixed[fixed$objectid=="47071", 4:5] <- c("DK050", "DK05") 

最終的な芖芚的チェック。


 ggplot()+ geom_polygon(data = gd_mun, aes(long, lat, group = group), color = brbg[9], fill = "grey90", size = .1)+ geom_polygon(data = gd_nuts3, aes(long, lat, group = group), color = brbg[3], fill = NA, size = 1)+ geom_point(data = fixed, aes(long, lat, color = nuts3), size = 1)+ theme_map(base_size = 15)+ theme(legend.position = c(1, 1), legend.justification = c(1, 1)) 

fig6
図6. 3぀の自治䜓の手動調敎埌の空間マッチングの再確認


今ではすべおが正垞です。


空間デヌタず統蚈デヌタを組み合わせたすファゞヌ結合


次のタスクは、空間デヌタず統蚈デヌタの簡単な䞀臎ではありたせんでした。 私が芋぀けた地方自治䜓のシェヌプファむルには、デンマヌク統蚈局が䜿甚する識別コヌドが含たれおいたせんでした。 そのため、デンマヌクの名前ず西ペヌロッパのコヌディングのすべおの喜びずずもに、垂町村を名前で空間デヌタセットず統蚈デヌタセットにドッキングする必芁がありたした。 2぀のデヌタセットでは、垂町村の名前の綎りが少し異なりたす。 そしお、数癟の自治䜓がありたす。 それはかなり退屈なルヌチンのようです。 あった 'Fuzzy String Matching'は、玠晎らしい開発者David Robinsonによっお曞かれたfuzzyjoinラむブラリヌでの救助ずその優れた実装です。


たず、垂町村名のデヌタを単玔化しお、もちろん䞡方のデヌタセットで小文字に倉換したした。 さらに、ドッキングの最初の詊みでは、文字「å」を代替のスペル「aa」に眮き換えるこずが理にかなっおいるこずが瀺されたした。 空間デヌタセットでは、各自治䜓の名前から「Kommune」ずいう単語も削陀したした。 叀い自治䜓の名前ずコヌドを含むデンマヌク統蚈局から小さなデヌタセットをダりンロヌドしたした 。


 # simplify municipalities names mun_geo <- mun_coord %>% transmute(name = sub(x = name, " Kommune", replacement = ""), objectid) %>% mutate(name = gsub(x = tolower(name), "Ã¥", "aa")) mun_stat <- read.csv2("https://ikashnitsky.imtqy.com/doc/misc/nuts2-denmark/stat-codes-names.csv", fileEncoding = danish_ecnoding) %>% select(name) %>% separate(name, into = c("code", "name"), sep = " ", extra = "merge") %>% mutate(name = gsub("\\s*\\([^\\)]+\\)", "", x = name)) %>% mutate(name = gsub(x = tolower(name), "Ã¥", "aa")) 

ファゞヌ結合を詊行しおいたす。


 # first attempt fuz_joined_1 <- regex_left_join(mun_geo, mun_stat, by = "name") 

出力は、271行ではなく278行のデヌタフレヌムです。これは、空間デヌタセットの䞀郚の自治䜓では、統蚈デヌタセットに耇数の䞀臎が芋぀かったこずを意味したす。 これらの問題のあるケヌスを芋぀けたす。


 # identify more that 1 match (7 cases) and select which to drop fuz_joined_1 %>% group_by(objectid) %>% mutate(n = n()) %>% filter(n > 1) 

 ## Source: local data frame [14 x 5] ## Groups: objectid [7] ## ## name.x objectid code name.yn ## <chr> <dbl> <chr> <chr> <int> ## 1 haslev 105112 313 haslev 2 ## 2 haslev 105112 403 hasle 2 ## 3 brÞnderslev 47003 739 rÞnde 2 ## 4 brÞnderslev 47003 805 brÞnderslev 2 ## 5 hirtshals 47037 817 hals 2 ## 6 hirtshals 47037 819 hirtshals 2 ## 7 rÞnnede 46378 385 rÞnnede 2 ## 8 rÞnnede 46378 407 rÞnne 2 ## 9 hvidebÊk 46268 317 hvidebÊk 2 ## 10 hvidebÊk 46268 681 videbÊk 2 ## 11 ryslinge 46463 477 ryslinge 2 ## 12 ryslinge 46463 737 ry 2 ## 13 aarslev 46494 497 aarslev 2 ## 14 aarslev 46494 861 aars 2 

そのため、7぀の垂町村に぀いお、2぀の䞀臎が芋぀かりたした。 ファゞヌ結合の次の反埩では、理想的ではない䞀臎を砎棄したす。


別の問題は、䞀郚の自治䜓ではたったく䞀臎しなかったこずです。


 # show the non-matched cases fuz_joined_1 %>% filter(is.na(code)) 

 ## name.x objectid code name.y ## 1 faxe 105120 <NA> <NA> ## 2 nykÞbing falsters 46349 <NA> <NA> ## 3 herstederne 46101 <NA> <NA> 

このようなケヌスは3぀しかなかったため、統蚈デヌタセットの名前に察応するように、空間デヌタセットでそれらを手動で修正したした。 2぀のケヌスでは、スペルの䞍正確さが原因で矛盟が発生し、別のケヌスでは、自治䜓の名前が倉曎されたした 。


 # correct the 3 non-matching geo names mun_geo_cor <- mun_geo mun_geo_cor[mun_geo_cor$name=="faxe", "name"] <- "fakse" mun_geo_cor[mun_geo_cor$name=="nykÞbing falsters", "name"] <- "nykÞbing f." mun_geo_cor[mun_geo_cor$name=="herstederne", "name"] <- "albertslund" 

次に、2回目のドッキングを詊みたす空間デヌタセットの名前が調敎されたす。


 # second attempt fuz_joined_2 <- regex_left_join(mun_geo_cor, mun_stat, by = "name") # drop non-perfect match fuz_joined_2 <- fuz_joined_2 %>% group_by(objectid) %>% mutate(n = n()) %>% ungroup() %>% filter(n < 2 | name.x==name.y) fuz_joined_2 <- fuz_joined_2 %>% transmute(name = name.x, objectid, code) 

パヌフェクト。 最埌のステップは、NUTSリヌゞョンを「objectid」フィヌルドで垂町村の叀い統蚈コヌドに添付するこずです。


 # finally, attach the NUTS info to matched table key <- left_join(fuz_joined_2, fixed, "objectid") 

NUTSレベルでの地方自治䜓デヌタの集玄


これたでの操䜜により、叀い自治䜓の統蚈コヌドず最新のNUTS地域を䞀臎させる、小さいながらも非垞に貎重なデヌタフレヌムが提䟛されたした。 残っおいるのは、叀いデヌタを集玄するこずだけです。 そしお、「キヌ」デヌタセットを統蚈に添付し、NUTS-3およびNUTS-2レベルで集蚈したす。


 # finally, we only need to aggregate the old stat data df_agr <- left_join(key, df, "code") %>% filter(!is.na(name)) %>% gather("year", "value", y2001:y2006) df_nuts3 <- df_agr %>% group_by(year, sex, age, nuts3) %>% summarise(value = sum(value)) %>% ungroup() df_nuts2 <- df_agr %>% group_by(year, sex, age, nuts2) %>% summarise(value = sum(value)) %>% ungroup() 

2001幎にデンマヌクのNUTS-3地域の劎働幎霢人口15〜64歳の割合を蚈算し、この情報を地図に衚瀺しおみたしょう。


 # total population in 2001 by NUTS-3 regions tot_01 <- df_nuts3 %>% filter(year=="y2001") %>% group_by(nuts3) %>% summarise(tot = sum(value, na.rm = TRUE)) %>% ungroup() # working-age population in 2001 by NUTS-3 regions working_01 <- df_nuts3 %>% filter(year=="y2001", age %in% paste0("a0", 15:64)) %>% group_by(nuts3) %>% summarise(work = sum(value, na.rm = TRUE)) %>% ungroup() # calculate the shares of working age population sw_01 <- left_join(working_01, tot_01, "nuts3") %>% mutate(sw = work / tot * 100) 

 # map the shares of working age population in 2001 by NUTS-3 regions ggplot()+ geom_polygon(data = gd_nuts3 %>% left_join(sw_01, c("id" = "nuts3")), aes(long, lat, group = group, fill = sw), color = "grey50", size = 1) + scale_fill_viridis()+ theme_map(base_size = 15)+ theme(legend.position = c(1, 1), legend.justification = c(1, 1)) 

fig7
図7. 2001幎のデンマヌクのNUTS-3地域における劎働幎霢人口15-64の割合


結果は珟実的に芋えたす-数倀は倧郜垂圏ず比范的倧郜垂がある地域で高くなっおいたす。





Source: https://habr.com/ru/post/J325564/


All Articles