본문 바로가기
데이터분석/R

[R 데이터분석 with 샤이니] 통계 분석과 시각화

by 버섯도리 2022. 7. 12.

> ## 08-1 관심 지역 데이터만 추출하기

> # Step 1 : 데이터 준비하기

> library(sf)
> setwd(dirname(rstudioapi::getSourceEditorContext()$path))
> load("./06_geodataframe/06_apt_price.rdata")
> load("./07_map/07_kde_high.rdata")
> grid <- st_read("./01_code/sigun_grid/seoul.shp")
Reading layer `seoul' from data source `D:\1_Study\1_BigData\01_R\02_Doit_R_Shiny\01_code\sigun_grid\seoul.shp' using driver `ESRI Shapefile'
Simple feature collection with 694 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 126.7645 ymin: 37.42899 xmax: 127.1835 ymax: 37.70146
Geodetic CRS:  GCS_unknown

> # Step 2 : 서울에서 가장 비싼 지역 찾기

> install.packages("tmap")
> library(tmap)
> tmap_mode('view')
tmap mode set to interactive viewing
tm_shape(grid) + tm_borders() + tm_text("ID", col = "red") +
+   #---# 래스터 이미지 그리기
+   tm_shape(raster_high) +
+   #---# 래스터 이미지 색상 패턴 설정
+   tm_raster(palette = c("blue", "green", "yellow", "red"), alpha = .4) +
+   #---# 기존 지도 설정
+   tm_basemap(server = c('OpenStreetMap'))


> # Step 3 : 전체 지역 / 관심 지역 저장하기

> library(dplyr)
> apt_price <- st_join(apt_price, grid, join = st_intersects) # 실거래+그리드 결합
> apt_price <- apt_price %>% st_drop_geometry() # 실거래에서 공간 속성 지우기
> all <- apt_price
> sel <- apt_price %>% filter(ID == 81016)
> dir.create("08_chart")
> save(all, file = "./08_chart/all.rdata")
> save(sel, file = "./08_chart/sel.rdata")

>

> ## 08-2 확률 밀도 함수 : 이 지역 아파트는 비싼 편일까?

> # Step 1 : 확률 밀도 분포로 변환하기

> setwd(dirname(rstudioapi::getSourceEditorContext()$path))
> load("./08_chart/all.rdata")
> load("./08_chart/sel.rdata")
> max_all <- density(all$py) ; max_all <- max(max_all$y)
> max_sel <- density(sel$py) ; max_sel <- max(max_sel$y)
> plot_high <- max(max_all, max_sel) # y축 최대값 찾기
> rm(list = c("max_all", "max_sel"))
> avg_all <- mean(all$py)
> avg_sel <- mean(sel$py)

> # Step 2 : 그래프 그리기

plot(stats::density(all$py), ylim=c(0, plot_high),
+      col="blue", lwd=3, main=NA)
abline(v = avg_all, lwd=2, col="blue", lty=2)
text(avg_all + avg_all*0.15, plot_high*0.1,
+      sprintf("%.0f", avg_all), srt=0.2, col="blue")
> lines(stats::density(sel$py), col="red", lwd=3)
abline(v = avg_sel, lwd=2, col="red", lty=2)
text(avg_sel + avg_sel*0.15, plot_high*0.1,
+      sprintf("%.0f", avg_sel), srt=0.2, col="red")

> ## 08-3 회귀 분석 : 이 지역은 일년에 얼마나 오를까?

> # Step 1 : 월별 거래가 요약하기

> setwd(dirname(rstudioapi::getSourceEditorContext()$path))
> load("./08_chart/all.rdata")
> load("./08_chart/sel.rdata")
> library(dplyr)
> library(lubridate)
> all <- all %>% group_by(month=floor_date(ymd, "month")) %>%
+   summarize(all_py = mean(py))
> sel <- sel %>% group_by(month=floor_date(ymd, "month")) %>%
+   summarize(sel_py = mean(py))

> # Step 2 : 회귀식 모델링하기

> fit_all <- lm(all$all_py ~ all$month)
> fit_sel <- lm(sel$sel_py ~ sel$month)
> coef_all <- round(summary(fit_all)$coefficients[2], 1) * 365 # 전체 지역 연도별 가격 변화 산출
> coef_sel <- round(summary(fit_sel)$coefficients[2], 1) * 365 # 관심 지역 연도별 가격 변화 산출

> # Step 3 : 그래프 그리기

> library(grid)
> # 차트 위에 회귀식을 표현하기 위해 textGrob() 함수 사용
> grob_all <- grobTree(textGrob(paste0("전체 지역 : ", coef_all, "만원(평당)"), x=0.05,
+                               y=0.88, hjust=0, gp=gpar(col="blue", fontsize=13, fontface="italic")))
> grob_sel <- grobTree(textGrob(paste0("관심 지역 : ", coef_sel, "만원(평당)"), x=0.05,
+                               y=0.95, hjust=0, gp=gpar(col="red", fontsize=16, fontface="bold")))
>

> install.packages("ggpmisc")
> library(ggpmisc)

> #---# 관심 지역 회귀선 그리기
> gg <- ggplot(sel, aes(x=month, y=sel_py)) +
+   theme(axis.text.x = element_text(angle = 90)) +
+   stat_smooth(method = 'lm', colour = 'dark grey', linetype = "dashed") +
+   geom_line(color = "red", size = 1.5) + xlab("월") + ylab("가격") +
+   theme_bw()
> #---# 전체 지역 회귀선 그리기
> gg + geom_line(data = all, aes(x=month, y=all_py), color = "blue", size = 1.5) +
+   #---# 주석(회귀식) 추가하기
+   annotation_custom(grob_all) +
+   annotation_custom(grob_sel)

`geom_smooth()` using formula 'y ~ x'
> # 2021년 항 해 동안 개포동 일대의 아파트 가격 상승률이 서울시 전체 평균보다 5배 이상 높다고 볼 수 있다.

> ## 08-4 주성분 분석 : 이 동네 단지별 특징은 무엇일까?

> # Step 1 : 주성분 분석하기

> setwd(dirname(rstudioapi::getSourceEditorContext()$path))
> load("./08_chart/sel.rdata")
> pca_01 <- aggregate(list(sel$con_year, sel$floor, sel$py, sel$area),
+                     by=list(sel$apt_nm), mean)
> colnames(pca_01) <- c("apt_nm", "신축", "층수", "가격", "면적")
> m <- prcomp(~ 신축 + 층수 + 가격 + 면적, data = pca_01, scale = T)
summary(m)
Importance of components:
                          PC1    PC2     PC3    PC4
Standard deviation     1.4836 1.1979 0.56678 0.2069
Proportion of Variance 0.5503 0.3587 0.08031 0.0107
Cumulative Proportion  0.5503 0.9090 0.98930 1.0000

> # Step 2 : 그래프 그리기

> install.packages("ggfortify")
> library(ggfortify)
> autoplot(m, loadings.label = T, loadings.label.size = 6) +
+   geom_label(aes(label = pca_01$apt_nm), size = 4)

> # 개포우성1과 선경2차는 평당 가격대가 높은 것으로 나타났으며, 동부센트레빌 아파트는 다른 아파트보다 신축이면서 면적도 크고 층수가 높은 모습을 보인다. 반면 상지리츠빌은 신축이면서 면적이 크지만 층수가 낮을 것을 알 수 있다.

 

 

 

 

 

 

 

출처 : 김철민, ⌜공공데이터로 배우는 R 데이터분석 with 샤이니⌟, 이지스퍼블리싱, 2022