California_example_visualizations

필요한 패키지 설치하기

먼저, 워킹디렉토리 지정한다. data.table과 ggplot2패키지를 설치한다.

setwd("C:\\Users\\user\\Desktop\\data.table\\dt_ex")

# 패키지를 설치한다.
library(data.table)
library(ggplot2)
source("ExtractIsoTime.R")
source("wtf.R")

CSV파일 불러오기

분석하기 위한 파일을 불러오자. 마크다운내에서 파일을 인식하기 위해 read.table앞에도 반드시 setwd를 코딩 해줘야한다.

setwd("C:\\Users\\user\\Desktop\\data.table\\dt_ex")
rawdat = read.table(file = "Database 2013-01-21 (8zQ4cW7T).csv", sep = ",", 
    quote = "\"", flush = FALSE, header = TRUE, nrows = -1, fill = FALSE, stringsAsFactors = FALSE, 
    na.strings = c("None", ""))
str(rawdat)
## 'data.frame':    19207 obs. of  11 variables:
##  $ charges_citation       : chr  "720 ILCS 5 12-3.4(a)(2) [16145" "625 ILCS 5 6-101 [12935]" "720 ILCS 5 12-3(a)(1) [10529]" "720 ILCS 550 5(c) [5020200]" ...
##  $ race                   : chr  "WH" "LW" "BK" "BK" ...
##  $ age_at_booking         : int  26 37 18 32 49 26 41 56 40 20 ...
##  $ gender                 : chr  "M" "M" "M" "F" ...
##  $ booking_date           : chr  "2013-01-20T00:00:00" "2013-01-20T00:00:00" "2013-01-20T00:00:00" "2013-01-20T00:00:00" ...
##  $ jail_id                : chr  "2013-0120171" "2013-0120170" "2013-0120169" "2013-0120167" ...
##  $ bail_status            : chr  NA NA NA NA ...
##  $ housing_location       : chr  "05-" "05-" "05-L-2-2-1" "17-WR-N-A-2" ...
##  $ charges                : chr  NA NA NA NA ...
##  $ bail_amount            : int  5000 10000 5000 50000 5000 5000 25000 5000 25000 10000 ...
##  $ discharge_date_earliest: chr  NA NA NA NA ...

“,"를 기준으로 객체를 나누게 되며, 객체가 요인으로 인식되지 못하도록 stringAsFactors를 F로 놓는다. None과 결측치는 R상에서 NA로 처리하게 한다. rawdat의 구조를 한번 보자.

dat = as.data.table(rawdat)
str(dat)
## Classes 'data.table' and 'data.frame':   19207 obs. of  11 variables:
##  $ charges_citation       : chr  "720 ILCS 5 12-3.4(a)(2) [16145" "625 ILCS 5 6-101 [12935]" "720 ILCS 5 12-3(a)(1) [10529]" "720 ILCS 550 5(c) [5020200]" ...
##  $ race                   : chr  "WH" "LW" "BK" "BK" ...
##  $ age_at_booking         : int  26 37 18 32 49 26 41 56 40 20 ...
##  $ gender                 : chr  "M" "M" "M" "F" ...
##  $ booking_date           : chr  "2013-01-20T00:00:00" "2013-01-20T00:00:00" "2013-01-20T00:00:00" "2013-01-20T00:00:00" ...
##  $ jail_id                : chr  "2013-0120171" "2013-0120170" "2013-0120169" "2013-0120167" ...
##  $ bail_status            : chr  NA NA NA NA ...
##  $ housing_location       : chr  "05-" "05-" "05-L-2-2-1" "17-WR-N-A-2" ...
##  $ charges                : chr  NA NA NA NA ...
##  $ bail_amount            : int  5000 10000 5000 50000 5000 5000 25000 5000 25000 10000 ...
##  $ discharge_date_earliest: chr  NA NA NA NA ...
##  - attr(*, ".internal.selfref")=<externalptr>

분석하기 편하도록 data.table형식으로 rawdat를 변환한 후, 그 구조를 보자. 위의 결과와 비슷하지만 형식이 변화하면서 분석에 용이하게 한다.

날짜의 포맷을 변경하기

아까 설치한 ExtractIsoTime 기능을 이용해 날짜의 포맷을 변경하자. 예를 들어 2013-01-20T00:00:00은 2013-01-20 00:00:00으로 변환된다.

dat$booking_date = ExtractIsoTime(dat$booking_date)
dat$discharge_date_earliest = ExtractIsoTime(dat$discharge_date_earliest)

몇 가지 값들을 변환해보기

race별로 값이 몇개인지 table을 그려보자

table(dat$race, useNA = "ifany")
## 
##    AS     B    BK    IN    LB    LT    LW     W    WH 
##   117    29 13879    13    68  1803  1239    44  2015

W와 WH, B와 BK는 비슷한 항목이라고 할 수 있으므로, 이 둘을 합쳐보자.

dat$race = sub("^W$", "WH", dat$race)
dat$race = sub("^B$", "BK", dat$race)

funtion "sub"를 사용하여 W와 B를 각각 WH와 BK로 대체하였는데, 어차피 race에는 한 값밖에 없으므로 dat$race = sub("W”, “WH”, dat$race) dat$race = sub(“B”, “BK”, dat$race) 라고 해도 되겠다.

table(dat$race, useNA = "ifany")
## 
##    AS    BK    IN    LB    LT    LW    WH 
##   117 13908    13    68  1803  1239  2059

table을 그려보았더니 처음에 그렸던 table과는 달리 B와 W가 대체되어 table상에 나타나지 않음을 확인할 수 있다.

몇가지 테이블을 그려보자

table(dat$gender, useNA = “ifany”)도 그려보고, 여러가지를 그려볼 수있다. 하지만 Chargs와 Charges_citation은 출력하기에 너무 큰 항목들이다. 그러므로 T)[1:10]을 코딩해서 가장 갯수가 많은 10개를 출력해보자.

# sort를 이용
sort(table(dat$charges_citation, useNA = "ifany"), T)[1:10]
## 
##  720 ILCS 570 402(c) [5101110] 720 ILCS 5 12-3.2(a)(1) [10416 
##                           1531                            623 
##           720 ILCS 5/9-1(a)(1)    625 ILCS 5 6-303(a) [13526] 
##                            559                            513 
##            720 ILCS 570/402(c)   720 ILCS 5 19-1(a) [1110000] 
##                            470                            390 
##                           <NA> 720 ILCS 5 12-3.2(a)(2) [10418 
##                            315                            306 
##   720 ILCS 5 19-3(a) [1120000]  720 ILCS 5 16A-3(a) [1060000] 
##                            302                            272
sort(table(dat$charges, useNA = "ifany"), T)[1:10]
## 
##                                         <NA> 
##                                         3052 
##               POSS AMT CON SUB EXCEPT(A)/(D) 
##                                         1839 
## FIRST DEGREE MURDER:INTENDS DEATH/GREAT HARM 
##                                          619 
##                        RET THEFT/DISP MERCH/ 
##                                          466 
##                 DOMESTIC BATTERY/BODILY HARM 
##                                          463 
##                                     BURGLARY 
##                                          461 
##                         RESIDENTIAL BURGLARY 
##                                          461 
##             ARMED ROBBERY ARMED WITH FIREARM 
##                                          308 
##                                      ROBBERY 
##                                          283 
##                       VIOLATION OF PROBATION 
##                                          265

기본 PLOt

# 범위, NA는 제거한다.
range(dat$booking_date, na.rm = TRUE)
## [1] "1993-01-16 KST" "2013-01-20 KST"
# x축은 열(변수), Y축은 번호이다.
plot(dat$discharge_date_earliest, 1:nrow(dat))

plot of chunk unnamed-chunk-9

plot(dat$booking_date, 1:nrow(dat))

plot of chunk unnamed-chunk-9

# 두개의 변수의 산점도
plot(dat$booking_date, dat$discharge_date_earliest)

plot of chunk unnamed-chunk-9

# 히스토그램도 그릴수 있다. (세분화하기위해 두번째 인자에 100을
# 코딩한다.)두개의 차이를 보자
hist(dat$bail_amount, 100)

plot of chunk unnamed-chunk-9

hist(dat$bail_amount)

plot of chunk unnamed-chunk-9

밑의 히스토그램은 조금 특별하다.

hist(pmin(dat$bail_amount, 1e+06), 100)

plot of chunk unnamed-chunk-10

pmin은 인자들을 병렬로 비교하면서, 각 원소별 최소값을 구한다. 위의 코드는 결국 1e+06과 비교해서 bail_amount값이 더 작으면 그 값이 나오고 크면 1e+06값을 반환한다.

# 제목 붙이기
plot(dat$age_at_booking, dat$bail_amount, main = "age by bail amount")

plot of chunk unnamed-chunk-11

다음의 코드는 위와 같은 데이터를 사용하지만, 데이터 변환을 시도하여 plot을 그렸다.

plot(log(bail_amount) ~ age_at_booking, dat, main = "age by log(bail amount)")

plot of chunk unnamed-chunk-12

plot(dat$age_at_booking, dat$bail_amount, main = “age by bail_amount)와 코드형식이 다르다, 위의 코드는 두번째 인자에서 어떤 데이터의 변수인지 지정해 줌으로서 변수를 인식할수 있게 된다.

Boxplot도 위와 비슷하다.

boxplot(bail_amount ~ age_at_booking, dat, main = "age by bail amount (much better)")

plot of chunk unnamed-chunk-13

# Boxplot에 범위제한을 건다.
boxplot(pmin(bail_amount, 5e+05) ~ age_at_booking, dat, main = "age by bail amount\n(changing the limits)")

plot of chunk unnamed-chunk-13

ggplot 그려보기

한눈에 비교하여 볼수 있는 ggplot을 그려보자.

ggplot(dat, aes(x = age_at_booking, fill = factor(race))) + geom_density(alpha = 0.5) + 
    facet_grid(race ~ .) + xlab("Age at booking") + ylab("Density by race") + 
    theme(plot.title = element_text(size = 20)) + labs(title = "Age at booking summary\nby race\n")

plot of chunk unnamed-chunk-14

race별로 age_at_booking의 density funtion을 그려보았다.

다음 코드는 세 개의 변수별로 변수별로 비교하여 볼 수 있다.


ggplot(dat, aes(x = age_at_booking, fill = factor(gender))) + geom_density(alpha = 0.7) + 
    facet_grid(race ~ .) + xlab("Age at booking") + ylab("Density by race") + 
    theme(plot.title = element_text(size = 20)) + labs(title = "Age at booking summary\nby gender and race\n")

plot of chunk unnamed-chunk-15

x축은 age_at_booking이고, race별로 그림이 그려졌다. 하지만 그 안에는 또 gender별로 그림이 겹쳐져 있어서 세 변수를 같이 비교하며 볼 수 있다.