Cookbook for R을 기반으로 하여 작성하였습니다.
이번 포스팅에서는
와이드 형식(wide format)에서 긴 형식(long format)으로
데이터를 변환하는 방법에 대해서 알아볼게요.
R에서 사용하는 많은 함수는
데이터가 와이드 형식이 아닌 긴 형식일 것으로 예상을 하고 있어요.
그러나 가끔 넓은 형식의 데이터를 사용하곤 해요.
그래서 두 형식 간의 데이터를 변환시키는 방법에 대해서 알고 있어야
각 상황에 맞는 데이터 분석을 할 수 있어요.
그럼 데이터 형식을 변환시키는 방법에 대해 알아볼게요.
두 형식 간에 변환을 할 수 있는 방법은 크게 아래 2가지예요.
1. tidyr 패키지의 gather()와 spread() 함수 사용
2. reshape2 패키지의 melt() 및 dcast() 함수 사용
(※ 참고로 tidyr 패키지는 reshape2 패키지보다 더 새로운 인터페이스 패키지입니다.)
※ 위의 2가지 이외에 다른 많은 방법들이 있는데,
여기에서 다루지 않고,
소개만 하고 넘어갈게요.
첫 번째는 reshape() 함수예요.
혼란스러울 수 있는데,
이것은 reshape2 패키지의 일부가 아닌
R에 기본적으로 설치되어 있는 함수예요.
두 번째는 stack()와 unstack() 함수입니다.
연습 데이터 생성
아래 2개의 데이터 프레임은 동일한 데이터를 보유하고 있지만,
와이드 및 롱 형식으로 데이터 표현방식이 다를 뿐이에요.
우선 와이드 형식의 데이터 프레임을 생성해 볼게요.
# 와이드(wide) 형식의 데이터 프레임 생성
olddata_wide <- read.table(header=TRUE, text='
subject sex control cond1 cond2
1 M 7.9 12.3 10.7
2 F 6.3 10.6 11.1
3 F 9.5 13.1 13.8
4 M 11.5 13.4 12.9
')
# olddata_wide 데이터에 대한 구조 파악
str(olddata_wide)
olddata_wide는 데이터 프레임이며,
4개의 관측치와 5개의 변수로 구성되어 있다는 것을 알 수 있어요.
subject 변수가 수치형 변수로 되어 있는데,
이후 분석을 위해서 factor형으로 변환할게요.
# subject 변수를 factor형으로 변환
olddata_wide$subject <- factor(olddata_wide$subject)
# 변환 후 olddata_wide 데이터에 대한 구조 파악
str(olddata_wide)
subject에 대한 변수형이 4개의 수준을 가지는 factor형으로 변환되었음을 확인할 수 있어요.
다음은 롱 형식의 데이터 프레임을 생성해 볼게요.
# 롱(long) 형식의 데이터 프레임 생성
olddata_long <- read.table(header=TRUE, text='
subject sex condition measurement
1 M control 7.9
1 M cond1 12.3
1 M cond2 10.7
2 F control 6.3
2 F cond1 10.6
2 F cond2 11.1
3 F control 9.5
3 F cond1 13.1
3 F cond2 13.8
4 M control 11.5
4 M cond1 13.4
4 M cond2 12.9
')
# olddata_long 데이터에 대한 구조 파악
str(olddata_long)
olddata_long 은 데이터 프레임이며,
12개의 관측치와 4개의 변수로 구성되어 있다는 것을 알 수 있어요.
subject 변수가 수치형 변수로 되어 있는데,
이후 분석을 위해서 factor형으로 변환할게요.
# subject 변수를 factor형으로 변환
olddata_long$subject <- factor(olddata_long$subject)
# 변환 후 olddata_long데이터에 대한 구조 파악
str(olddata_long)
subject에 대한 변수형이 4개의 수준을 가지는 factor형으로 변환되었음을 확인할 수 있어요.
tidyr 패키지를 활용한 데이터 프레임 형식 변환
<와이드 형식에서 롱 형식으로의 변환: gather() 함수 사용>
olddata_wide
install.packages('tidyr') # tidyr 패키지 설치
library(tidyr) # tidyr 패키지 로딩
# gather() 함수의 주요 인수:
# - data: Data object
# - key: 데이터 열의 이름으로 만들어진 새로운 키(key) 열의 이름
# - value: 새로운 값 열의 이름
# - ...: 값을 포함하는 소스 열의 이름
# - factor_key: 새 키 열을 factor로의 처리 여부
data_long <- gather(data = olddata_wide,
key = condition,
value = measurement,
control:cond2,
factor_key = TRUE)
data_long
이 예에서 수집되는 소스 열은 control:cond2로 지정됐어요.
이는 control과 cond2 사이에 있는 모든 열을 사용한다는 것을 의미해요.
이를 수행하는 또 다른 방법은 아래와 같이 열 이름을 개별적으로 지정하는 것입니다.
gather(olddata_wide, condition, measurement, control, cond1, cond2)
프로그래밍 방식으로 gather()를 사용해야 하는 경우, 열 이름이 포함된 변수를 사용해야 할 수도 있어요.
keycol <- "condition"
valuecol <- "measurement"
gathercols <- c("control","cond1","cond2")
gather(olddata_wide,keycol,valuecol,gathercols)
변수 열의 factor level의 이름을 바꾸고 정렬할 수도 있어요.
# factor 이름 변경하기 (cond1 -> first)
levels(data_long$condition)[levels(data_long$condition)=="cond1"] <- "first"
# factor 이름 변경하기 (cond2 -> second)
levels(data_long$condition)[levels(data_long$condition)=="cond2"] <- "second"
# 정렬하기 (첫 번째 정렬 키: subject / 두 번째 정렬 키: condition)
data_long <- data_long[order(data_long$subject, data_long$condition), ]
data_long
<롱 형식에서 와이드 형식으로의 변환: spread() 함수 사용>
olddata_long
library(tidyr)
# spread() 함수 인수
# - data: Data object
# - key: 새로운 열 이름을 포함하는 열 이름
# - value: 값을 포함하는 열 이름
data_wide <- spread(data = olddata_long, key = condition, value = measurement)
data_wide
데이터를 더 멋지게 보이게 하는 몇 가지 선택사항이 있어요.
# cond1을 first으로 변경하기
names(data_wide)[names(data_wide)=="cond1"] <- "first"
# cond2를 second으로 변경하기
names(data_wide)[names(data_wide)=="cond2"] <- "second"
# 열을 재 정렬하기
data_wide <- data_wide[, c(1,2,5,3,4)]
data_wide
factor level의 순서는 열의 순서를 결정합니다.
level 순서는 모양을 변경하기 전에 변경하거나 나중에 열을 다시 정렬할 수 있으니, 참고하세요.
reshape2 패키지를 활용한 데이터 프레임 형식 변환
<와이드 형식에서 롱 형식으로의 변환: melt() 함수 사용>
olddata_wide
install.packages('reshape2') #reshape2 패키지 설치
library(reshape2) # reshape2 패키지 로드
# id.vars 지정: 유지는 하지만, 분할하지 않을 변수
melt(olddata_wide, id.vars=c("subject", "sex"))
출력을 좀 더 쉽게 작업할 수 있도록 하는 유용한 옵션이 있어요.
data_long<-melt(olddata_wide,
# ID 변수들 - 유지는 하지만, 분할하지 않을 변수
id.vars=c("subject","sex"),
# 소스 열
measure.vars=c("control","cond1","cond2"),
# 원본을 식별할 대상 열의 이름
variable.name="condition",
# 측정 열
value.name="measurement"
)
data_long
measure.vars를 생략하면 Melt는 자동으로 다른 모든 변수를 id.vars로 사용하고,
id.vars를 생략하면 그 반대에 해당합니다.
variable.name을 지정하지 않으면 해당 열의 이름을 "변수"로 지정하고,
value.name을 생략하면 해당 열의 이름을 "측정"으로 지정하게 됩니다.
변수 열의 factor level 이름을 바꿀 수 있어요.
# factor 이름 변경하기 (cond1 -> first)
levels(data_long$condition)[levels(data_long$condition)=="cond1"]<-"first"
# factor 이름 변경하기 (cond2 -> second)
levels(data_long$condition)[levels(data_long$condition)=="cond2"]<-"second"
# 정렬하기 (첫 번째 정렬 키: subject / 두 번째 정렬 키: condition)
data_long<-data_long[order(data_long$subject,data_long$condition),]
data_long
<롱 형식에서 와이드 형식으로의 변환: dcast() 함수 사용>
다음 코드는 dcast를 사용하여 데이터를 재구성하는 경우이고,
이 함수는 데이터 프레임을 위한 것이에요.
배열이나 행렬로 작업하는 경우 acast를 사용하셔야 해요.
olddata_long
library(reshape2)
data_wide<-dcast(olddata_long, subject+sex~condition,value.var="measurement")
data_wide
데이터를 더 멋지게 보이게 하는 몇 가지 선택사항이 있어요.
# factor 이름 변경하기 (cond1 -> first)
names(data_wide)[names(data_wide)=="cond1"] <- "first"
# factor 이름 변경하기 (cond2 -> second)
names(data_wide)[names(data_wide)=="cond2"] <- "second"
# 정렬하기 (첫 번째 정렬 키: subject / 두 번째 정렬 키: condition)
data_wide <- data_wide[, c(1,2,5,3,4)]
data_wide
factor level의 순서는 열의 순서를 결정합니다.
level 순서는 모양을 변경하기 전에 변경하거나 나중에 열을 다시 정렬할 수 있으니, 참고하세요.
'R 프로그래밍 > R advance' 카테고리의 다른 글
오픈 API를 활용한 공공데이터 불러오기(데이터 포맷: json) (0) | 2022.01.27 |
---|---|
오픈 API를 활용한 공공데이터 불러오기(데이터 포맷: xml) (25) | 2022.01.07 |
[R그래픽스]커뮤니케이션을 위한 그래픽 (0) | 2021.07.20 |
[R데이터다루기]데이터 변환 (0) | 2021.07.18 |
[R그래픽스]데이터 시각화 (0) | 2021.07.17 |
댓글