가로형/세로형 변환(reshape2::melt/dcast)
- 데이터 준비
library(dplyr)
library(tidyr)
mtcars$name = rownames(mtcars); rownames(mtcars) = NULL
mtcars %>% select(name, am, mpg, cyl, disp) -> mcars
head(mcars, 4)
## name am mpg cyl disp ## 1 Mazda RX4 1 21.0 6 160 ## 2 Mazda RX4 Wag 1 21.0 6 160 ## 3 Datsun 710 1 22.8 4 108 ## 4 Hornet 4 Drive 0 21.4 6 258
데이터
library(dplyr)
library(tidyr)
mtcars$name = rownames(mtcars); rownames(mtcars) = NULL
mtcars %>% select(name, am, mpg, cyl, disp) -> mcars
head(mcars)
## name am mpg cyl disp ## 1 1 1 21.0 6 160 ## 2 2 1 21.0 6 160 ## 3 3 1 22.8 4 108 ## 4 4 0 21.4 6 258 ## 5 5 0 18.7 8 360 ## 6 6 0 18.1 6 225
패키지 reshape2
의 활용
패키지 reshape2
의 melt
/dcast
함수를 사용하여 세로형/가로형 변환을 할 수도 있다. 다음 코드는 앞에서 gather
/spread
함수가 한 세로형/가로형 변환을 melt
/dcast
함수를 써서 재연하고 있다. 결과가 같다!
library(reshape2)
## ## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr': ## ## smiths
## The following objects are masked from 'package:data.table': ## ## dcast, melt
mcarsLong <-
mcars %>% gather(-name, -am,
mpg, cyl, disp,
key='key', value='value',
factor_key=TRUE)
mcarsWide <-
mcarsLong %>% spread(key='key', value='value')
mcarsLong2 <-
mcars %>% melt(id=c("name","am"),
measure.vars = c("mpg", "cyl", "disp"),
variable.name = "key", value.name = 'value')
mcarsWide2 <-
mcarsLong2 %>% dcast(name + am ~ key) -> mcarsWide2
all.equal(mcarsLong, mcarsLong2)
all.equal(mcarsWide, mcarsWide2)
## [1] TRUE ## [1] TRUE
차근 차근 두 코드를 비교해보자. gather
의 경우 데이터 테이블의 열에서 명시적으로 지정된 열은 측정변수로, 그 외의 변수는 식별자(identifier)로 활용한다. 식별자를 명시하려면 변수명 앞에 -
를 붙이면 된다. 이렇게 하면 세로형으로 변환하려는 데이터프레임의 모든 열을 식별자와 측정변수로 구분하여 gather
함수에 알려줄 수 있다. (무엇보다 우리가 식별자와 측정변수를 명확하게 구분할 수 있다.) key=
와 value=
는 변환된 세로형의 열이름으로 여기서는 기본값인 key
와 value
로 하였다. 그리고 factor_key=TRUE
로 하여 melt
의 결과와 일치하게 만들었다. (factor_key=TRUE
는 key
열을 팩터형으로 만든다.)
gather
를 melt
함수로 구현하려면 역시 식별자와 측정변수를 명시한다. id=
에 식별자 변수이름을 문자열 벡터로, measure.vars=
에 측정변수 이름을 문자열 벡터로 입력한다. 그리고 variable.name=
과 value.name=
은 gather
의 key=
와 value=
에 대응하는 인자이다. 세로형의 열 이름을 결정한다. dcast
의 기본값은 variable
과 value
이지만 gather
결과와 일치하게 만들기 위해 key
와 value
로 하였다.
spread(dat, key='key', value='value')
는 일종의 어구로 생각했다. (열이름이 바뀌었다면 반영해서 key=
과 value=
를 바꾼다.) 이를 dcast
로 구현하는 방법을 알아보자. 형식은 dcast(dat, ~ )
꼴이고, ~
의 왼쪽에 식별자 변수를, 오른쪽에 key
를 적는다.
이렇게 melt
/dcast
로 세로형/가로형 변환을 할 수 있음을 보였다. 그런데 똑같은 일을 왜 굳이 다른 함수로 하는건가? melt
와 dcast
는 세로형/가로형 변환 뿐 아니라 집계통계치(또는 요약 통계치)을 구하는 데에도 사용할 수 있기 때문이다.
앞의 코드에서 mcarsLong
과 mcarsLong2
의 식별자는 name
과 am
이었다. 만약 am
의 값에 따른 측정변수 mpg
, cyl
, disp
의 평균을 알고 싶다면 다음과 같이 한다.
dcast(mcarsLong2, am ~ key, fun.aggregate=mean)
## am mpg cyl disp ## 1 0 17.14737 6.947368 290.3789 ## 2 1 24.39231 5.076923 143.5308
앞의 가로형 변환(dcast(mcarsLong2, name + am ~ key)
)과 비교해 보면 ~
의 좌측에 name
이 빠진 것을 확인할 수 있다. 그리고 결과를 보면 표의 좌측에 am
의 값이 나열되고, 우측에 측정변수(key
)가 나열되어 있음을 볼 수 있다.
다시 dcast(mcarsLong2, name + am ~ key)
또는 원자료를 살펴보자.
dcast(mcarsLong2, name + am ~ key) %>% head(5)
## name am mpg cyl disp ## 1 1 1 21.0 6 160.0 ## 2 10 0 19.2 6 167.6 ## 3 11 0 17.8 6 167.6 ## 4 12 0 16.4 8 275.8 ## 5 13 0 17.3 8 275.8
이 데이터프레임 첫 행을 보자. 이름(name
)이 AMC Javelin
이고 am==0
(자동기어)인 차의 3가지 측정변수 mpg
, cyl
, disp
을 보여준다. 만약 식별자로 쓰인 name
과 am
에서 name
을 생략하고 am
만 사용한다면 am==0
인 여러 자동차의 데이터가 한 행에 모이게 된다. 이들을 하나의 값으로 바꾸기 위해서 fun.aggregate=
의 함수를 적용한 결과가 dcast(mcarsLong2, am ~ key, fun.aggregate=mean)
이다.
이것은 앞에서 봤던 다차원 행렬의 한 차원을 제거하여 차원을 축소하면서 집계 함수를 적용하는 것과 비슷하다. dcast
는 차원을 축소하면서 원하는 형태의 표로 자료를 변환할 수 있다. 다음의 코드를 실행해보자.
dcast(mcarsLong2, key ~ am, fun.aggregate=mean)
## key 0 1 ## 1 mpg 17.147368 24.392308 ## 2 cyl 6.947368 5.076923 ## 3 disp 290.378947 143.530769
dcast(mcarsLong2, . ~ am + key, fun.aggregate=mean)
## . 0_mpg 0_cyl 0_disp 1_mpg 1_cyl 1_disp ## 1 . 17.14737 6.947368 290.3789 24.39231 5.076923 143.5308
dcast(mcarsLong2, . ~ key + am, fun.aggregate=mean)
## . mpg_0 mpg_1 cyl_0 cyl_1 disp_0 disp_1 ## 1 . 17.14737 24.39231 6.947368 5.076923 290.3789 143.5308
dcast(mcarsLong2, am + key ~ ., fun.aggregate=mean)
## am key . ## 1 0 mpg 17.147368 ## 2 0 cyl 6.947368 ## 3 0 disp 290.378947 ## 4 1 mpg 24.392308 ## 5 1 cyl 5.076923 ## 6 1 disp 143.530769
참고자료 {-}
R에는 tidyr
의 gather
/spread
과 reshape2
의 melt
/dcast
함수 외에도 다양한 함수를 사용하여 세로형/가로형 변환과 관련된 작업을 할 수 있다. 좀 더 알고 싶은 독자는 다음의 자료를 참고하기 바란다.
Leave a comment