# 2-1. 위도, 경도 얻어올 도시명 불러오기


city <- country_city %>% select(city)

city <- unique(city)                                            # 16225 obs.

country <- unique(country_city$country) %>% as.data.frame()   # 237 obs.


'ggmap'으로 위도, 경도를 요청하는 쿼리는 개수 제한이 있습니다. (free 계정은 2,500개, API키를 입력하면 그 이상입니다.)  중복 요청을 피하기 위해 도시과 국가명을 분리, 중복되는 값들은 'rJava'패키지에 있는 'unique'함수로 제거해주었습니다. 요청은 물론 차집합을 구하는 'setdiff'나 조인함수를 사용할 때 중복되는 데이터가 있으면 개수가 안맞게 될 수 있으므로, 미리 중복제거(De-duplication)를 하는 것을 추천드립니다. 



# 2-2. 위도, 경도 얻어오기

# Trial 1

gcity01 <- head(city, 2500)

gcode01 <- geocode(gcity01$city, source="google")

table(is.na(gcode01))


> gcity01 <- head(city, 2500)

> gcode01 <- geocode(gcity01$city, source="google")


> table(is.na(gcode01))


FALSE  TRUE

4078   822


'geocode' 1번째 시도라는 의미에서 [gcity01]라는 이름을 지어 "head"를 이용해 2,500개의 도시명을 넣어주었습니다. 이를 이용해 'ggmap' 패키지의 'geocode'를 실행했고 lat, log 각각 2,500개씩 총 5,000개의 값을 요청했습니다. 'is.na'로 확인해본 결과 1,644개의 값을 정상적으로 받았다는 것을 알 수 있었습니다. (한국어와 일본어 도시명은 각각 해당 영문 도시명과 같다고 연결해 줄 예정이므로 영문 국가명을 이용해 위, 경도를 요청했습니다.)


* 참고: 에러 발생 시
gcode01 <- geocode(gcity01$city, source="google")

>  gcode01 <- geocode(gcity01$city, source="google")
query max exceeded, see ?geocode.  current total = 2500

위와 같은 에러 문이 뜨는 경우 문장을 그대로 해석해보아도 알 수 있지만, 하루 쿼리 요청 제한을 초과한 것입니다. 저는 API key를 사용하지 않았기 때문에 요청 쿼리가 2,500개를 넘어가면 위의 메세지가 떴습니다. Stack of flow에 다양한 방법이 올라와 있지만 저는 그냥 하루에 개수를 맞춰 요청하는 방법을 사용하고 있습니다.


rcity01 <- gcity01 %>%

           mutate(lon=gcode01$lon, lat=gcode01$lat) %>%

           filter(!is.na(lat) & !is.na(lon))

table(is.na(rcity01))


> table(is.na(rcity01))


FALSE

6117


위, 경도를 받아오는 데 실패하여 NA값이 저장된 행을 제거해주기 위하여 'filter'함수를 사용해 1번째 시도 결과(result)로 저장해주었습니다. 'is.na'로 조회해본 결과 NA가 아닌 값만 잘 남아있는 것을 확인할 수 있었습니다. 실제로 출력하면 아래와 같이 도시와 해당 위, 경도를 확인할 수 있습니다.


head(rcity01)


> head(rcity01, 10)

             city lon     lat

1 les Escaldes 1.538786 42.51008 2 Andorra la Vella 1.521835 42.50632 3 Umm al Qaywayn 55.713391 25.52048 4 Ras al-Khaimah 55.980417 25.67413 5 Dubai 55.270783 25.20485 6 Dibba Al-Fujairah 56.259403 25.59112 7 Dibba Al-Hisn 56.273375 25.61819 8 Sharjah 55.420932 25.34626 9 Al Fujayrah 56.248228 25.41108 10 Al Ain 55.802312 24.13016


제대로 값이 들어온 것을 확인한 후! 일일 쿼리가 제한되어있는 만큼! 정상적으로 얻어진 데이터는 아래와 같이 바로바로 파일로 저장해두었습니다.

rcity <- rcity01
write.csv(rcity, file='rcity.csv')

> rcity <- rcity01
> write.csv(rcity, file='rcity.csv')

원본 데이터에서 [rcity01] 데이터에 담긴, 즉 위, 경도가 제대로 얻어진 도시만 제거해서 두 번째 시도 시 사용할 데이터를 만들겠습니다.


city_t1 <- rcity01 %>% select(city)

city01 <- setdiff(city, city_t1)

str(city01)


> city01 <- setdiff(city, city_t1)

> str(city01)

'data.frame': 14196 obs. of  1 variable:

 $ city: chr  "Fier-Çifçi" "Luau" "Mercedes" "Concepción del Uruguay" ...


경도 얻기에 성공한 데이터의 도시명만 [city_t1]에 담아 'dplyr' 패키지에서 제공하는 'setdiff' 함수를 이용하여 모든 도시명이 담긴 [city] 데이터에서 [city_t1]을 제거했습니다. 한마디로 차집합을 구한 것입니다. 결과 16,225개에서 14,196개로 작업 대상이 줄어들었음을 알 수 있었습니다. 


# Trial 2


1번 시도에서 했던 과정과 동일하게 진행하였습니다. 첫 번째 시도에 만들어진 차 집합을 자료를 이용하는 부분이 있으니, 두 번째 시도 까지는 기록하고 이후는 생략하겠습니다.


gcity02 <- head(city01, 2500)

gcode02 <- geocode(gcity02$city, source="google")

table(is.na(gcode02))


> gcity02 <- head(city01, 2500)

> gcode02 <- geocode(gcity02$city, source="google")


> table(is.na(gcode02))


FALSE  TRUE

 786  4214


rcity02 <- gcity02 %>%

           mutate(lon=gcode02$lon, lat=gcode02$lat) %>%

           filter(!is.na(lat) & !is.na(lon))

table(is.na(rcity02))


> table(is.na(rcity02))


FALSE

1179


head(rcity02)


> head(rcity02, 10)

city lon lat

1 Lintong 109.2142 34.36727 2 Linping 120.3064 30.42061 3 Linhai 121.1312 28.84544 4 Linfen 111.5190 36.08801 5 Xishan 102.6644 25.03830 6 Liaocheng 115.9855 36.45703 7 Lianran 102.4710 24.91699 8 Wuwei 102.6382 37.92827 9 Liangxiang 116.1411 39.75284 10 Leshan 103.7657 29.55212


rcity <- rbind(rcity01, rcity02)

write.csv(rcity, file='rcity.csv')


> rcity <- rbind(rcity01, rcity02)

> write.csv(rcity, file='rcity.csv')


두 번째 시도 후, 처음 얻었던 자료와 합쳐 저장하기 위해 'rbind'를 사용하여 두 데이터 프레임을 하나의 데이터 프레임으로 만들었습니다.


city_t2 <- rcity02 %>% select(city)

city02 <- setdiff(city01, city_t2)

str(city02)


> str(city02)

'data.frame': 13792 obs. of  1 variable:

 $ city: chr  "Dubai" "Dibba Al-Hisn" "Al Fujayrah" "Abu Dhabi" ...




# 2-3. 데이터 최종 확인 및 정리


result01 <- inner_join(country_city, rcity, by="city")

result02 <- result01 %>% select(city, lat, lon, country, city_ko, country_ko, city_ja, country_ja)

write.csv(result02, "geocode_city.csv")

head(result02)


> result01 <- inner_join(country_city, rcity, by="city")

> result02 <- result01 %>% select(city, lat, lon, country, city_ko, country_ko, city_ja, country_ja)

> write.csv(result02, "geocode_city.csv")

> head(result02)

          city lat     lon country              city_ko country_ko city_ja        country_ja

1 les Escaldes     42.51008 1.538786 Andorra            레에스칼데스 안도라 <NA>          アンドラ

2 Andorra la Vella 42.50632 1.521835 Andorra             안도라라벨라 안도라 アンドララベリャ アンドラ

3 Umm al Qaywayn    25.52048 55.713391 United Arab Emirates 음알케이웨이 아랍 에미리트 <NA>           アラブ首長国連邦

4 Ras al-Khaimah 25.67413 55.980417 United Arab Emirates 라스알카이마 아랍 에미리트 ラスアルカイマ アラブ首長国連邦

5 Dubai             25.20485 55.270783 United Arab Emirates 두바이        아랍 에미리트 ドバイ          アラブ首長国連邦

6 Dibba Al-Fujairah 25.59112 56.259403 United Arab Emirates 디바알푸자이라 아랍 에미리트  <NA>          アラブ首長国連邦


도시, 국가명이 있던 원본 파일에 위, 경도를 'inner_join'으로 연결하여 최종 파일을 만들었습니다. 


+ Recent posts