본문 바로가기

배운 책들 정리/공공데이터로 배우는 R 데이터 분석 with 샤이니

공공데이터 with 샤이니 4~5 - 데이터 전처리, 지오 코딩

1. 데이터 전처리 CP 4

1) 실습 : 형태 변환 후 파일 저장 

# 300개 csv 파일 생성 됨.
# 파일만 가져옴 filenames <- dir("./raw_data/")
# 파일 통합
filenames <- list.files("./raw_data/",full.names = T)
# install.packages("plyr")
library(plyr)
apt_price <- ldply(as.list(filenames), read.csv)
head(apt_price)
tail(apt_price)
# 파일로 저장
write.csv(apt_price, file = "./data/apt_price.csv")

ldply

이름 형태로 변환

> apt_price <- ldply(as.list(filenames), read.csv)

데이터 분석에 필요한 형태로 변환

head
tail

뽑힌 결과값

 

 

2) 데이터 전처리

# 데이터 전처리
# 정답은 없음 = 전처리 순서나 규칙 등이 없음
# 의미 없는 데이터를 지우는 방법 => 질, 신뢰할 수 있는 데이터 만들기
# 결측치, 이상치, 중복, 공백 등
# 아파트 가격 통합 데이터 불러오기
apt_price <- read.csv("./data/apt_price.csv")
head(apt_price)
str(apt_price)
# x.1, x는 필요 없음
# 아파트 가격 변수 검토 -> 전체 변수 검토로 
# (아파트가격만 하면 결측치 뜸)
# table(is.na(apt_price$price))
# 결측치 확인
table(is.na(apt_price))
# 결측치 제거
apt_price <-  na.omit(apt_price)
# 결측치 다시 확인
table(is.na(apt_price))
# 공백 제거
head(apt_price$price) # 공백 확인
library(stringr)
str_trim(apt_price$price)
# 전체 데이터 공백 제거
# 숫자 2 = 열 단위로 적용
# 숫자 1 = 행 단위로 적용
# 이걸 안하면 열이 10개면 10번 반복하는거임
apt_price <- as.data.frame(apply(apt_price, 2, str_trim))
head(apt_price)
head(apt_price$price) # 공백 확인
str(apt_price)
# 데이터 모든 열의 값들이 가지고 있는 공백이 사라졌음을 확인할 수 있음

table(is.na(apt_price))

결측치 확인!!

as.data.frame(apply(apt_price, 2, str_trim))

공백 제거

 

 

 

 

3) 데이터 다듬기

# 데이터 다듬기
# 거래 연월일 날짜 변수 만들기 = 거래연월일 합치기
library(lubridate)
library(dplyr)

apt_price <-   apt_price %>% 
  mutate(ymd = make_date(year, month, day)) 
head(apt_price,3)
# 거래 연월 변수 만들기 = 모든 일을 1일로 변경
# 거래 연월만 필요해서 일은 전부 1일로 변경
apt_price$ym <- floor_date(apt_price$ymd, "month")
head(apt_price,3)
# 아파트 가격 숫자형으로 만들기
head(apt_price$price, 3)
# 중간에 comma가 있음 => 제거 후에 숫자형으로 변환
apt_price$price <- apt_price$price %>% 
  str_replace(",","") %>%
  as.numeric()


head(apt_price,3)
class(apt_price$price)  
table(is.na(apt_price))

floor_date(apt_price$ymd, "month")

거래 연월일에서 일자를 전부 1일로 변경

 

4) 주소 조합하기 (주소 변수 생성, 시+구 데이터 가져오기 등등)

# 주소 변수 만들기 = 시 + 구 + 동 + 지번 + 아파트 이름
str(apt_price)
head(apt_price$apt_nm,50)
# (이후 문자 제거
apt_price$apt_nm <- gsub("\\(.*","",apt_price$apt_nm)
head(apt_price$apt_nm,30)
# 시 + 구 데이터 가져오기
loc <- read.csv("./data/sigun_code.csv", fileEncoding = "UTF-8")
head(loc)
apt_price <- merge(apt_price, loc, by = "code")
head(apt_price)
# 주소 조합
apt_price$juso <- paste0(apt_price$addr_2, " ",
       apt_price$dong_nm, " ",
       apt_price$jibun, " ",
       apt_price$apt_nm)

5) 변수 생성 : 건축연도

# 건축연도
str(apt_price)
class(apt_price$con_year)
# 건축연도를 이용해서 계산할 때 문제가 생기므로 숫자로 변환
apt_price$con_year <- apt_price$con_year %>% 
  as.numeric()
head(apt_price$con_year)
class(apt_price$con_year)


# 키워드 검색
apt_price %>% 
  filter(str_detect(apt_nm, "롯데" ))

 

6) 변수 생성 : 평당 가격

# 평당 가격
apt_price$price
apt_price$area # 문자임
# 면적 변수가 문자형이므로 계산에 문제가 생겨서 숫자로 변환
apt_price$area<- apt_price$area %>% 
  as.numeric() %>%
  round(0)
head(apt_price$area)
# 평당 가격 3.3m^2 = (아파트 가격/ 면적) * 3.3
apt_price$py <-  round((apt_price$price/apt_price$area)*3.3, 0)
head(apt_price$py)

 

7) 아파트 층수 변수 숫자로 변환

# 아파트 층수 변수
str(apt_price)
head(apt_price$floor)
# 층수 계산에 문제가 생길 수 있으므로 숫자로 변환
apt_price$floor <- apt_price$floor %>% 
  as.numeric()
head(apt_price$floor)
summary(apt_price$floor)

apt_price$floor <- apt_price$floor %>% 
abs()

summary(apt_price$floor)
> as.numeric()

 

숫자 데이터로 변환

 

8) 거래 변수 추가 후 저장

# 거래건수 변수 추가
apt_price$cnt <- 1
str(apt_price$cnt)

# 저장하기
colnames(apt_price)
apt_price <- apt_price %>% 
  select(ymd, ym, year, code, addr_1, apt_nm, juso, price, con_year, area, floor, py, cnt)
head(apt_price)

write.csv(apt_price, file = "./data/preprocess.csv")
# 키워드 검색
apt_price %>% 
  filter(str_detect(floor, "-" ))

write.csv(apt_price, file = "./data/preprocess.csv")

저장된 데이터

2. 카카오맵 API로 지오 코딩하기 : 5장

1) 지오 코딩 준비 : 데이터 불러오기 & 라이브러리 불러오기

# 지오코딩 준비하기
# https://developers.kakao.com/
# 카카오 계정 로그인
# 내 어플리케이션 클릭
# 애플리케이션 추가하기 클릭
# map / 테스트 입력, 체크사항 체크, 저장 클릭
# 앱을 클릭하면 REST API에 인증키가 있음
# REST API 키 : b582c9672b3dfce8c47961abb94862f1

# 전처리 완료한 데이터 불러오기
str(apt_price)
apt_price <- read.csv("./data/preprocess.csv")
head(apt_price)
apt_juso <- data.frame(apt_price$juso)
# 중복 데이터 제거
apt_juso <- data.frame(apt_juso[!duplicated(apt_juso),])
head(apt_juso)
str(apt_juso)

# 주소를 좌표(경도, 위도)로 변환하는 지오코딩
add_list <- list()
cnt <- 0
kakao_key = "b582c9672b3dfce8c47961abb94862f1" # 각자 애플리케이션에 있는 REST API 키 입력

# 라이브러리 준비
# 전처리가 잘못됨
library(httr)
# install.packages("RJSONIO")
library(RJSONIO)
library(data.table)
library(dplyr)

2) for문

# 시작
for (i in 1:nrow(apt_juso)) {
  # 주소로 검색해도 JSON 데이터가 없는 경우를 대비하여 예외 처리
  tryCatch({
    long_lat <- GET(url = "https://dapi.kakao.com/v2/local/search/address.json" ,
                    query = list(query=apt_juso[i,]) ,
                    add_headers(Authorization = paste0("KakaoAK ", kakao_key))) 
    coord_xy <- long_lat %>% 
      content(as = "text") %>%  
      RJSONIO::fromJSON() # 리스트로 이쁘게 담아줌
    
    cnt = cnt+1
    add_list[[cnt]] <- data.table(apt_juso = apt_juso[i,],
                                  coord_x = coord_xy$documents[[1]]$x , #경도 long
                                  coord_y = coord_xy$documents[[1]]$y #위도 lat 
    )
    # 진행 상황 메시지
    msg <- paste0(i, '/', nrow(apt_juso))
    cat(msg, "\n")}, error=function(e){cat(conditionMessage(e), "\n")
  })

    }

3) 지오 코딩 결과 확인 및 저장

# 지오 코딩 결과 확인
length(add_list)  

# 지오 코딩 결과 저장
# 리스트 -> 데이터프레임 변환
juso_geocoding <- rbindlist(add_list) 
str(juso_geocoding)
# 좌표 숫자형 변환
juso_geocoding$coord_x <- as.numeric(juso_geocoding$coord_x) 
juso_geocoding$coord_y <- as.numeric(juso_geocoding$coord_y)
# 결측치 확인
table(is.na(juso_geocoding))
# 결측치 없음
# 데이터 저장
write.csv(juso_geocoding, file = "./data/05_juso_geocoding.csv", row.names = F)

 

* 핵심

- 한글을 바로  쓸 수 없어서 디코드를 엔코딩 해줘야 함

 

 

728x90
반응형
LIST