R 데이터 재구조화 reshape 패키지 melt(), cast() 함수, reshape2의 acast(), dcast() 함수, tidyverse의 spread() 함수
R 분석과 프로그래밍/R 데이터 전처리 2015. 8. 29. 11:31DB에 들어있는 데이터를 내렸을 때, 설문조사 데이터를 받았을 때, 원천 거래 데이터를 받았을 때, 혹은 분석 과정 중의 데이터 셋이 분석가가 하고자 하는 통계분석, 데이터마이닝 분석이나 ggplot2 등의 그래프/시각화를 위해 필요한 데이터 구조로 딱 맞아떨어지지 않는 경우가 굉장히 많습니다.
이때 필요한 것이 데이터를 분석 목적, 기법에 맞게 자유자재로 변형하여 재구조화하는 일입니다.
엑셀에서 Pilvot Table 생성하는 것이 제일 이해하기 쉬운 예가 될거 같습니다. 세로로 길게 늘어서 있는 원 데이터를 가로와 세로로 틀을 잡아 주고, 가운데에는 value 값에 대해서 개수를 센다든지, 합계를 낸다든지, 평균을 구한다든지 하는 함수를 적용하는 것을 해보셨을 겁니다.
비유를 해보자면, 레고블록으로 높이 세워진 탑을 모양과 색깔별로 레고 블록을 잘 분해한 다음에, 이를 재료로 해서 가로와 세로로 넓게 펴고 높이는 낮추어서 새로운 탑을 만드는 것이라고 생각해보는 것도 이해하는데 도움이 될거 같습니다.
이때 데이터 재구조화하는 기준 변수를 무엇으로 하느냐, 가로로 길게 늘어뜨릴 변수는 또 무엇으로 하느냐, 가운데에 값을 볼 때 무슨 함수를 사용해서 값을 계산해서 볼 것이냐에 따라서 다양한 경우의 수가 발생하게 됨에 따라 말로 모든 것을 설명하는 것이 무리가 있습니다. 따라서 아래에 reshape 패키지의 melt(), cast() 함수를 몇 가지 경우의 수에 적용해 보면서 원래 값이 이후에 어떻게 바뀌는지를 유심히 보시고, 필요한 상황에 맞는 R script를 참고하시면 되겠습니다.
[ reshape 패키지 내 melt()함수, cast() 함수 사용 데이터 재구조화 예시 ]
예제로 사용할 데이터는 MASS 패키지에 내장되어 있는 Cars93 데이터 프레임의 차종(Type), 제조국(Origin), 도시 연비(MPG.city), 고속도로 연비(MPG.highway) 4개의 변수를 사용해서 몇가지의 경우의 수를 조합해 가면서 데이터를 녹였다가 (melt) 재구조화 (cast) 를 해보겠습니다.
|
데이터 양이 너무 많으면 melt(), cast()를 적용했을 때 데이터 구조가 변화하는 모양을 보기가 쉽지 않기 때문에 차종(Type) 중에서 개수가 적은 "Compact"와 "Van" 만 선별해서 예제로 사용하겠습니다.
> table(Cars93$Type) Compact Large Midsize Small Sporty Van 16 11 22 21 14 9 > > Cars93_sample <- subset(Cars93, + select = c(Type, Origin, MPG.city, MPG.highway), + subset = (Type %in% c("Compact", "Van"))) > > Cars93_sample Type Origin MPG.city MPG.highway 3 Compact non-USA 20 26 12 Compact USA 25 36 13 Compact USA 25 34 16 Van USA 18 23 17 Van USA 15 20 21 Compact USA 23 28 25 Compact USA 22 27 26 Van USA 17 21 33 Compact USA 22 27 36 Van USA 15 20 43 Compact non-USA 24 31 55 Compact non-USA 26 34 56 Van non-USA 18 24 58 Compact non-USA 20 29 65 Compact non-USA 24 30 66 Van non-USA 17 23 68 Compact USA 24 31 70 Van USA 18 23 74 Compact USA 23 31 78 Compact non-USA 20 26 82 Compact non-USA 23 30 87 Van non-USA 18 22 89 Van non-USA 17 21 90 Compact non-USA 21 30 92 Compact non-USA 21 28 > dim(Cars93_sample) [1] 25 4 |
reshape 패키지의 melt(), cast() 함수를 이용한 데이터 재구조화 |
R의 reshape 패키지는 별도의 설치가 필요합니다.
# reshape package installation, library > library(reshape) |
이제 melt(data, id.vars, measure.vars) 함수를 사용해서 기존 데이터셋을 녹여보도록 하겠습니다.
> # melt() > Cars93_sample_melt <- melt(data = Cars93_sample, + id.vars = c("Type", "Origin"), + measure.vars = c("MPG.city", "MPG.highway")) > > Cars93_sample_melt Type Origin variable value 1 Compact non-USA MPG.city 20 2 Compact USA MPG.city 25 3 Compact USA MPG.city 25 4 Van USA MPG.city 18 5 Van USA MPG.city 15 6 Compact USA MPG.city 23 7 Compact USA MPG.city 22 8 Van USA MPG.city 17 9 Compact USA MPG.city 22 10 Van USA MPG.city 15 11 Compact non-USA MPG.city 24 12 Compact non-USA MPG.city 26 13 Van non-USA MPG.city 18 14 Compact non-USA MPG.city 20 15 Compact non-USA MPG.city 24 16 Van non-USA MPG.city 17 17 Compact USA MPG.city 24 18 Van USA MPG.city 18 19 Compact USA MPG.city 23 20 Compact non-USA MPG.city 20 21 Compact non-USA MPG.city 23 22 Van non-USA MPG.city 18 23 Van non-USA MPG.city 17 24 Compact non-USA MPG.city 21 25 Compact non-USA MPG.city 21 26 Compact non-USA MPG.highway 26 27 Compact USA MPG.highway 36 28 Compact USA MPG.highway 34 29 Van USA MPG.highway 23 30 Van USA MPG.highway 20 31 Compact USA MPG.highway 28 32 Compact USA MPG.highway 27 33 Van USA MPG.highway 21 34 Compact USA MPG.highway 27 35 Van USA MPG.highway 20 36 Compact non-USA MPG.highway 31 37 Compact non-USA MPG.highway 34 38 Van non-USA MPG.highway 24 39 Compact non-USA MPG.highway 29 40 Compact non-USA MPG.highway 30 41 Van non-USA MPG.highway 23 42 Compact USA MPG.highway 31 43 Van USA MPG.highway 23 44 Compact USA MPG.highway 31 45 Compact non-USA MPG.highway 26 46 Compact non-USA MPG.highway 30 47 Van non-USA MPG.highway 22 48 Van non-USA MPG.highway 21 49 Compact non-USA MPG.highway 30 50 Compact non-USA MPG.highway 28 > dim(Cars93_sample_melt) [1] 50 4
|
이렇게 melt()함수를 사용해 녹인 데이터를 cast()함수를 사용해서 재구조화 해보겠습니다. 세로와 가로에 무슨 변수를 넣을지가 결정되었다면 아래의 예제를 참고해서 원하는 구조에 맞게 R script를 작성하시면 되겠습니다. (말로 설명하기가 쉽지가 않습니다 ^^;) function 란에는 R에서 사용할 수 있는 통계량 함수를 사용하면 되며, 이번 예제에서는 평균(mean) 함수를 사용하였습니다.
> # cast() > options(digits=3) # 소숫점 너무 밑에 까지 나오지 않도록 설정 > > # 한개의 id.var 기준(세로) & variable(가로) 조합의 value 값에 mean 함수 적용 > cast(data = Cars93_sample_melt, Type ~ variable, fun = mean) Type MPG.city MPG.highway 1 Compact 22.7 29.9 2 Van 17.0 21.9 > cast(data = Cars93_sample_melt, Origin ~ variable, fun = mean) Origin MPG.city MPG.highway 1 USA 20.6 26.8 2 non-USA 20.7 27.2 > > cast(data = Cars93_sample_melt, Type + Origin ~ variable, fun = mean) Type Origin MPG.city MPG.highway 1 Compact USA 23.4 30.6 2 Compact non-USA 22.1 29.3 3 Van USA 16.6 21.4 4 Van non-USA 17.5 22.5 >
> cast(data = Cars93_sample_melt, Type ~ Origin + variable, fun = mean) Type USA_MPG.city USA_MPG.highway non-USA_MPG.city non-USA_MPG.highway 1 Compact 23.4 30.6 22.1 29.3 2 Van 16.6 21.4 17.5 22.5 > cast(data = Cars93_sample_melt, Origin ~ Type + variable, fun = mean) Origin Compact_MPG.city Compact_MPG.highway Van_MPG.city Van_MPG.highway 1 USA 23.4 30.6 16.6 21.4 2 non-USA 22.1 29.3 17.5 22.5 >
> cast(data = Cars93_sample_melt, Type + variable ~ Origin, fun = mean) Type variable USA non-USA 1 Compact MPG.city 23.4 22.1 2 Compact MPG.highway 30.6 29.3 3 Van MPG.city 16.6 17.5 4 Van MPG.highway 21.4 22.5
Origin variable Compact Van
1 USA MPG.city 23.4 16.6
2 USA MPG.highway 30.6 21.4
3 non-USA MPG.city 22.1 17.5
4 non-USA MPG.highway 29.3 22.5
|
reshape2 패키지의 acast() 함수를 이용한 데이터 재구조화 |
> library(gcookbook) > data(cabbage_exp) > cabbage_exp Cultivar Date Weight sd n se 1 c39 d16 3.18 0.9566144 10 0.30250803 2 c39 d20 2.80 0.2788867 10 0.08819171 3 c39 d21 2.74 0.9834181 10 0.31098410 4 c52 d16 2.26 0.4452215 10 0.14079141 5 c52 d20 3.11 0.7908505 10 0.25008887 6 c52 d21 1.47 0.2110819 10 0.06674995 > > #install.packages("reshape2") > library(reshape2) > cabbage_exp_cast <- acast(data = cabbage_exp + , Cultivar ~ Date + , value.var = 'Weight' + , fun.aggregate = mean + #, fill = 0 # if you want to fill the missing value with '0' + , drop = TRUE) > cabbage_exp_cast d16 d20 d21 c39 3.18 2.80 2.74 c52 2.26 3.11 1.47
|
tidyverse 패키지의 spread() 함수를 이용한 데이터 재구조화 |
> # load data > library(gcookbook) > data(cabbage_exp) > cabbage_exp Cultivar Date Weight sd n se 1 c39 d16 3.18 0.9566144 10 0.30250803 2 c39 d20 2.80 0.2788867 10 0.08819171 3 c39 d21 2.74 0.9834181 10 0.31098410 4 c52 d16 2.26 0.4452215 10 0.14079141 5 c52 d20 3.11 0.7908505 10 0.25008887 6 c52 d21 1.47 0.2110819 10 0.06674995 > > # reshape data using tidyverse > library(tidyverse) > > # melt first (long format) > cabbage_exp_melt <- cabbage_exp %>% + group_by(Cultivar, Date) %>% + summarise(Weight = mean(Weight)) > > # cast second (wide format) > cabbage_exp_cast <- spread(cabbage_exp_melt, key = c("Date"), value = "Weight", fill = 0) > > print(cabbage_exp_cast) # A tibble: 2 x 4 # Groups: Cultivar [2] Cultivar d16 d20 d21 <fct> <dbl> <dbl> <dbl> 1 c39 3.18 2.8 2.74 2 c52 2.26 3.11 1.47
|
이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^
'R 분석과 프로그래밍 > R 데이터 전처리' 카테고리의 다른 글
R 중복 없는 유일한 관측치 선별하기(extracting unique elements) : unique(), !duplicated() (24) | 2016.01.30 |
---|---|
R clearing of console, datasets, plots in RStudio (0) | 2015.09.17 |
R 데이터 재구조화 reshape 패키지 melt(), cast() 함수, reshape2의 acast(), dcast() 함수, tidyverse의 spread() 함수 (19) | 2015.08.29 |
R 에서 SQL 사용 sqldf 패키지, 집계 aggregate() 함수 (3) | 2015.08.28 |
R 데이터 변환 : (6) 시그널 데이터 변환 - FFT (Fast Fourier Transform) (8) | 2015.08.16 |
R 데이터변환 : (5) 차원 축소 - (5-2) 요인분석(factor analysis) (8) | 2015.08.08 |
댓글을 달아 주세요
공부하는 데 많은 도움이 되어 제 블로그에 공유하였습니다.
내용 변환없이, 그리고 원작자 출처 명확히 밝혔습니다.
좋은 글 감사합니다.
블로그 포스팅의 부분 인용 & 출처 기입은 괜찮구요,
그게 아니라 블로그 포스팅 통 스크랩일 경우는
(1) 제목 & 링크,
or (2) (개인학습 용도로) 비공개 전환,
or (3) (개인학습 용도로) 즐겨찾기 추가를 해서
이용하시기 바랍니다.
네이버의 '스크랩' 같이 원본 그대로 옮겨 포스팅하는 경우(비록 출처를 밝혔다 하더라도) 외국 블로깅에서는 있을 수 없는 일이예요.
제가 블로깅 하는 원칙이기도 하구요, 블로거들이 서로 지키는 예절이기도 합니다.
이해해 주시기 바랍니다.
질문있어요~ 이글에 맞는지는 모르겠지만..
칼럼1(id)에는 725284 , 칼럼2(keyword_count)에는 대출:4^출금:3^이자:2
이런식의 데이터가 담겨 있습니다.
칼럼2의 데이터는 id별 담겨있는키워드와 그 횟수인데요. 대출이라는 키워드가 4번 출금이라는 키워드 3번 나타나고 있다는 뜻입니다
이걸
id, 키워드, 카운트 3개의 칼럼으로 해서 행하나에 키워드와 카운트를 한개씩만 들어가게하려면 어떻게해야할까요?
예를들어
3301 대출 4
3301 출금 3
3301 이자 2
for문으로 만들어보긴했는데 원본의 1400여개 행을 작업해서 7만개 행으로 쪼개는데 20분이 드네요.. 너무오래걸려서 혹시 적절한 다른 방법이 있을까해서 질문드립니다~
(1) 2번째 칼럼 쪼개기
(2) subset()으로 id, column(대출, 출금, 이자 별로 각 각), value(각 column 별 회수) 로 쌍으로 해서 칼럼 개수만큼 실행 (이 예제는 대출, 출금, 이자 3번)
(3) rbind로 3개 데이터셋 합치기
이렇게 한번 해보시지요.
(2)subset부분이 이해가 잘 안가는데요.. 음.. 이 데이터셋의 뜻은 각 콜당 핵심키워드의 빈도를 나타내는 거구요. 키워드의 종류 수는 제한이 없습니다. 즉 1행 2열에 들어가있는 키워드 종류가 대출 출금 이자 3가지라면 2행 2열에는 15가지일 수도 있습니다. 실제데이터에서 첫번째꺼는 46개구요.
즉 2열의 한칸마다 데이터가 너무 길어서 보기 좋게하려고 키워드를 쪼개서 세로로 형태를 바꾸려고 하는거구요 ㅠㅠ
그러면 루프 프로그래밍하신거 쓰셔야겠네요.
감사합니다~
AshtrayK님,
문자열 분리해서 세로로 형태바꾸는 방법에 대해서는 아래 포스팅 참고하세요.
http://rfriend.tistory.com/238
혼자 공부중인데 많은 도움받고 갑니당~
건영님, 반갑습니다.
댓글 감사합니다. ^^
안녕하세요!! 혹시 아까 오후에 질문 남겼었는데 확인해주시면 정말 감사하겠습니다ㅠㅠ
위에 답글 남겼습니다. 확인해보시구요. :-)
참, 질문 남기실때는 다른 분들도 참고할 수 있도록 공개모드로 질문 남겨주세요.
분석하려는 목적, 대상이 뭐냐에 따라서 결정이 되겠지요.
구글링 통해서 tidyverse 매뉴얼을 참고하시기 바랍니다.
알겠습니다! 답변 감사합니다!