과연 우리가 탐색하려는 데이터가 제대로 된 것인가?
- 데이터가 분석이나 시각화를 위해 필요한 데이터 구조로 딱 맞아떨어지지 않는 경우가 굉장히 많음.
- 이때 필요한 것이 데이터를 분석 목적, 기법에 맞게 자유자재로 변형하여 재구조화하는 일!
melt(),cast(),merge()를 사용한다.library(reshape)가 필요하다.
예시 : 데이터 만들기
r
rm(list=ls())
library(reshape)
set.seed(101)
a = 101
b = 2
c = 50
x = cbind(rep(1:a, each=2), rep(1:b, times=b),
matrix(rnorm(a*b*c), nrow=a*b))
datas1 = as.data.frame(x)
names(datas1) = c("ID", "time", paste(rep(LETTERS[1:25], each=2),
rep(c(1, 2), times=25), sep="."))
이 데이터의 구조를 보자.
r
> str(datas1)
'data.frame': 202 obs. of 52 variables:
$ ID : num 1 1 2 2 3 3 4 4 5 5 ...
$ time: num 1 2 1 2 1 2 1 2 1 2 ...
$ A.1 : num -0.326 0.552 -0.675 0.214 0.311 ...
$ A.2 : num 0.424 -0.79 1.21 0.895 -0.101 ...
$ B.1 : num 0.1419 -0.8251 -1.3712 0.0249 1.581 ...
$ B.2 : num 0.16784 1.21561 0.25515 1.61906 -0.00412 ...
$ C.1 : num 2.153 0.958 -0.509 -0.568 1.5 ...
$ C.2 : num -0.0714 1.0474 -0.2668 0.958 -0.9828 ...
$ D.1 : num 1.309 -1.703 0.836 0.68 -0.348 ...
$ D.2 : num 0.865 -0.918 -0.782 -1.491 1.023 ...
$ E.1 : num 0.487 -0.482 0.87 0.88 1.375 ...
$ E.2 : num 0.2023 -3.0987 -0.0649 -1.6907 0.4512 ...
- id : 1,2,3으로 구성
- time : 1교시, 2교시
- A.1 = A반 1번 문항 점수
데이터들의 변수가 너무 많다. (알파벳별, 숫자별로 쪼개짐.)
따라서 이 데이터는 clustering하기 적절하지 않으며, 재구조화가 필요하다.
melt & cast 이용하기
melt()를 이용해 ID와 time 외 모든 변수들을 합쳐보자.
남겨놓을 변수는 파라미터 id에 저장한다.
r
ID time variable value
1 1 1 A.1 -0.3260365
2 1 2 A.1 0.5524619
3 2 1 A.1 -0.6749438
4 2 2 A.1 0.2143595
5 3 1 A.1 0.3107692
6 3 2 A.1 1.1739663
해답
r
datas2 = melt(datas1, id=c("ID", "time"))
head(datas2)
이제, cast()를 이용해 다시 데이터를 원래대로 돌려보자.
- 파라미터로
id+time~variable as.data.frame()을 앞에 씌워준다.
head(), all.equal(), summary()를 확인해보면 같다는 것을 알 수 있다.
해답
r
# 생성
datas3 = as.data.frame(cast(datas2, ID+time~variable))
# 확인하기
head(datas3[, 1:6])
all.equal(datas1, datas3)
summary(datas1-datas3)
cast의 응용
문항별 평균 점수를 만들어보자.
해답
r
# cast()를 이용한 문항별 평균점수
cast(datas2, time~variable, mean)
# with()를 이용한 A.1의 문항별 평균점수
with(datas1, tapply(A.1, time, mean))
merge() : 두 데이터프레임 합치기
이번에도 새 데이터프레임을 만들어보자.
r
v = 5
x2 = cbind(rep(1:(a-v), each=2),
rep(1:b, times=a-v),
matrix(rnorm((a-v)*b*2), nrow=(a-v)*b))
datas_svy = as.data.frame(x2)
names(datas_svy)<-c("ID", "time", "HT", "WT")
만든 새 데이터프레임 datas_svy를 datas1과 비교해보자.
확연히 다른 구조를 가지고 있을 것이다.
해답
r
dim(datas1)
dim(datas.svy)
merge()를 이용해 두 데이터프레임을 합쳐보자.
- datas1은 1~4번째 변수. datas_svy는 그대로.
- 기준 : ID
해답
r
merged_1 = merge(datas1[, 1:4], datas_svy, by="ID")
str(merged_1)
head(merged_1)
r
ID time.x A.1 A.2 time.y HT WT
1 1 1 -0.3260365 0.2680658 1 0.27200077 -0.10297269
2 1 1 -0.3260365 0.2680658 2 0.84604437 -0.09016754
3 1 2 0.5524619 -0.5922083 1 0.27200077 -0.10297269
4 1 2 0.5524619 -0.5922083 2 0.84604437 -0.09016754
5 2 1 -0.6749438 2.1334864 1 0.06113811 -0.05251098
6 2 1 -0.6749438 2.1334864 2 1.97423975 -0.79844060
- datas1은 1~4번째 변수. datas_svy는 그대로.
- 기준 : ID, time, x의 모든 파트 살리기
해답
r
merged_2 = merge(datas1[, 1:4], datas.svy, by=c("ID", "time"),
all.x=T)
str(merged_2)
head(merged_2)
r
ID time A.1 A.2 HT WT
1 1 1 -0.3260365 0.2680658 0.27200077 -0.10297269
2 1 2 0.5524619 -0.5922083 0.84604437 -0.09016754
3 2 1 -0.6749438 2.1334864 0.06113811 -0.05251098
4 2 2 0.2143595 1.1727487 1.97423975 -0.79844060
5 3 1 0.3107692 0.7467610 -1.97843100 1.35451019
6 3 2 1.1739663 -0.2305087 -0.31165479 -2.04389356
해답
r
names(datas5)[apply(is.na(datas5), 2, sum)>0]