우리는 데이터 분석을 수행하면서 다양한 데이터 변환 작업을 수행하게 된다. 이는 데이터가 원래 특정 분석을 염두에 두고 만들어지는 경우가 거의 없기 때문이며, 사실 애초 데이터 설계를 할 때 분석 목적을 알기도 불가능하다는 게 가장 큰 원인이 아닐까 한다. 이런 연유로 전체 데이터 분석 작업에서 70% 혹은 80% 이상이 이런 데이터 변환 및 전처리 작업에서 소모된다.
이런 전처리 작업에서의 반복된 패턴을 잡게 되면 이를 처리할 수 있는 함수나 모듈들을 만들 수 있으며, 이렇게 만들어진 많은 함수들이 R 시스템에 통합되어 있다. 따라서 특정 함수를 발견하고 메뉴얼을 읽어도 이게 왜 이렇게 쓰이는지 정확히 이해못하는 경우는 아직 이 함수를 써야될 상황을 만나지 못해서 그런거라 생각하면 된다.
수많은 R 패키지가 있으나 그중에서 사용자들이 가장 많이 사용하는 몇몇 패키지들을 살펴보면 이들 패키지들을 만든 핵심 철학을 살펴볼 수 있는 것들이 있다.
plyr
, reshape2
, ggplot2
패키지들을 살펴보면 공통점이 있다. Hadley교수가 만들었다는 것과, 이들은 모두 Hadley교수가 정의한 분석하기 좋은 데이터(Tidy Data)를 위한 툴킷들이라는 것이다.
Hadley 교수가 정의한 단정한 데이터는 아래와 같은 특징을 가진다.
- 각 변수는 개별의 열(column)으로 존재한다.
- 각 관측치는 행(row)를 구성한다.
- 각 테이블은 단 하나의 관측기준에 의해서 조직된 데이터를 저장한다.
주변의 많은 데이터들은 위의 조건을 만족시키지 않은 경우가 많고 이를 기반으로 바로 시각화를 하거나 분석에 들어가고 모델링을 하게 되면 매번 다르지만 비슷한 작업들을 반복하게 되는 것이다. 이를 위해 먼저 위 세가지 조건에 맞게 데이터를 변환을 시키고 변환된 데이터를 기준으로 본격적인 분석 작업을 수행하게 되면 여러 반복적인 작업을 줄일 수 있다는 이야기다.
사실 위 조건은 plyr
, reshape2
, ggplot2
패키지를 사용하게 되면 아주 쉽게 조건을 만족시킬 수 있다.
library(ggplot2)
library(reshape2)
library(plyr)
load(url("http://dl.dropboxusercontent.com/u/8686172/pew.RData"))
head(raw)
## religion <$10k $10-20k $20-30k $30-40k $40-50k $50-75k
## 1 Agnostic 27 34 60 81 76 137
## 2 Atheist 12 27 37 52 35 70
## 3 Buddhist 27 21 30 34 33 58
## 4 Catholic 418 617 732 670 638 1116
## 5 Don't know/refused 15 14 15 11 10 35
## 6 Evangelical Prot 575 869 1064 982 881 1486
## $75-100k $100-150k >150k Don't know/refused
## 1 122 109 84 96
## 2 73 59 74 76
## 3 62 39 53 54
## 4 949 792 633 1489
## 5 21 17 18 116
## 6 949 723 414 1529
종교별 수입에 대한 조사 결과를 보여주는 데이터이다.
위와 같은 데이터는 옆으로 길게 뻣은 PPT에서 볼 수 있는 데이터 형태인데, 1번의 조건부터 부합되지 않는다는 것을 알 수 있다. 이런 데이터를 단정하게 만들기 위한 방법은 수입(income)을 하나의 열로 만들고, 빈도수를 또 하나의 별도의 열로 만드는 것이다.
아마도 이런 작업은 넓은 데이터를 길게 만들 것이다.
paw <- raw[, -c(8, 9, 10, 11)]
melted <- melt(paw, measure.vars = c(2, 3, 4, 5, 6, 7), variable.name = "income",
value.name = "freq")
head(melted)
## religion income freq
## 1 Agnostic <$10k 27
## 2 Atheist <$10k 12
## 3 Buddhist <$10k 27
## 4 Catholic <$10k 418
## 5 Don't know/refused <$10k 15
## 6 Evangelical Prot <$10k 575
tail(melted)
## religion income freq
## 103 Muslim $50-75k 23
## 104 Orthodox $50-75k 47
## 105 Other Christian $50-75k 14
## 106 Other Faiths $50-75k 63
## 107 Other World Religions $50-75k 7
## 108 Unaffiliated $50-75k 528
reshape2
패키지의 melt()
함수를 사용하면 이 작업을 한번에 수행 할 수 있으며, 변형된 데이터를 보면 단정한 데이터의 세가지 조건을 모두 만족 시키는 것을 알 수 있다.
이를 ggplot2
를 이용해 한줄의 코드로 바로 시각화 할 수 있다. 아마도 애초에 주어진 데이터를 가지고 바로 시각화를 하고자 했다면 이런 그래프를 만들기 위한 ad-hoc한 데이터 작업을 해야 했을 것이다.
ggplot(melted, aes(religion, freq)) + geom_bar(aes(fill = income), stat = "identity") +
theme(axis.text.x = element_text(angle = 45))
종교에 따른 수입의 빈도를 누적 히스토그램으로 표현했는데, 종교별 상대적 비교보다는 종교 내에서 비율을 좀더 부각시켜 보기 위한 작업을 한다면 plyr
패키지를 사용해 종교별 누적합을 계산해 종교내 빈도의 비율을 계산하면 된다.
물론 이렇게 변환된 데이터도 단정한 데이터이므로 바로 ggplot2
에서 시각화가 가능하다.
melted <- ddply(melted, .(religion), mutate, freq_sum = sum(freq))
melted <- ddply(melted, .(religion, income), summarise, freq_precent = freq/freq_sum)
head(melted)
## religion income freq_precent
## 1 Agnostic <$10k 0.06506
## 2 Agnostic $10-20k 0.08193
## 3 Agnostic $20-30k 0.14458
## 4 Agnostic $30-40k 0.19518
## 5 Agnostic $40-50k 0.18313
## 6 Agnostic $50-75k 0.33012
ggplot(melted, aes(religion, freq_precent)) + geom_bar(aes(fill = income), stat = "identity") +
theme(axis.text.x = element_text(angle = 45))
우리가 분석을 할 때 데이터를 어떻게 전처리를 해야 목적하는 분석을 할지는 쉽게 판단이 가능하다. 하지만 목적 데이터를 바로 만들기 전에 위에서 정의한 단정한 데이터를 먼저 만들어 이를 기반으로 추가적인 변형작업을 하는것이 좀더 체계적인 접근방법이 아닐까 하는 생각을 해본다.
개인적으로 Hadley교수를 좋아하는 이유는 바로 스스로 데이터 분석/처리를 해보고 반복적인 작업을 패턴화 해 이런 패키지를 만들어 대중에게 제공하는 것이라 생각한다.
물론 교수 스스로 정의한 바를 위한 툴킷들이지만 사용자들이 많다는 것은 그만큼 효용성이 있다는 것을 반증하는 것이 아닐까 한다.
분석하기 좋은 데이터(Tidy Data) by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.