먼저, 워킹디렉토리 지정한다. data.table과 ggplot2패키지를 설치한다.
setwd("C:\\Users\\user\\Desktop\\data.table\\dt_ex")
# 패키지를 설치한다.
library(data.table)
library(ggplot2)
source("ExtractIsoTime.R")
source("wtf.R")
분석하기 위한 파일을 불러오자. 마크다운내에서 파일을 인식하기 위해 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
# 범위, 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(dat$booking_date, 1:nrow(dat))
# 두개의 변수의 산점도
plot(dat$booking_date, dat$discharge_date_earliest)
# 히스토그램도 그릴수 있다. (세분화하기위해 두번째 인자에 100을
# 코딩한다.)두개의 차이를 보자
hist(dat$bail_amount, 100)
hist(dat$bail_amount)
밑의 히스토그램은 조금 특별하다.
hist(pmin(dat$bail_amount, 1e+06), 100)
pmin은 인자들을 병렬로 비교하면서, 각 원소별 최소값을 구한다. 위의 코드는 결국 1e+06과 비교해서 bail_amount값이 더 작으면 그 값이 나오고 크면 1e+06값을 반환한다.
# 제목 붙이기
plot(dat$age_at_booking, dat$bail_amount, main = "age by bail amount")
다음의 코드는 위와 같은 데이터를 사용하지만, 데이터 변환을 시도하여 plot을 그렸다.
plot(log(bail_amount) ~ age_at_booking, dat, main = "age by log(bail amount)")
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)")
# Boxplot에 범위제한을 건다.
boxplot(pmin(bail_amount, 5e+05) ~ age_at_booking, dat, main = "age by bail amount\n(changing the limits)")
한눈에 비교하여 볼수 있는 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")
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")
x축은 age_at_booking이고, race별로 그림이 그려졌다. 하지만 그 안에는 또 gender별로 그림이 겹쳐져 있어서 세 변수를 같이 비교하며 볼 수 있다.