지난 포스팅에서는 R data.table에서 := 를 사용한 참조에 의한 얕은 복사(shallow copy)의 부작용과 copy() 함수를 사용한 깊은 복사(deep copy)에 대하여 알아보았습니다. 


이번 포스팅에서는 R data.table 에서 melt() 와 dcast() 함수를 사용해서 효율적으로 재구조화 (efficient reshaping of R data.table) 하는 방법을 소개하겠습니다. 


R reshape 패키지의 melt(), cast() 함수와 유사하므로 활용법에 있어서 어렵거나 특별한 것은 없습니다. 다만 R data.table은 재구조화의 과정이 내부적으로 전부 C 언어로 수행되므로 매우 빠르고 또 메모리 효율적입니다. 


(1) data.table 을 녹여서 넓은 자료구조를 길게 (wide to long) 재구조화 해주는 melt() 함수

(2) data.table 을 주조하여 긴 자료구조를 넓게 (long to wide) 재구조화 해주는 dcast() 함수





  (1) melt() : data.table 을 녹여서 넓은 자료구조를 길게 (wide to long) 재구조화


data.table 패키지를 불러오고, MASS 패키지에 내장되어 있는 Cars93 데이터프레임에서 행 1~5번 까지, 그리고 6개 칼럼만 선별해와서 예제로 사용할 간단한 data.table을 만들어보겠습니다. 



library(data.table)

library(MASS)


DT <- data.table(Cars93[1:5, c("Model", "Type", "DriveTrain", "Length", "Width", "Weight")])

print(DT)

# Model    Type DriveTrain Length Width Weight

# 1: Integra   Small      Front    177    68   2705

# 2:  Legend Midsize      Front    195    71   3560

# 3:      90 Compact      Front    180    67   3375

# 4:     100 Midsize      Front    193    70   3405

# 5:    535i Midsize       Rear    186    69   3640




이제 위에서 만든 data.table DT를 melt() 함수를 사용하여 ID(id.vars) 변수는 모델("Model"), 차종("Type"), 동력전달장치("DriveTrain") 의 3개 변수로 하고, 측정값 변수(measure.vars)로는 길이("Length"), 폭("Width"), 무게("Weight")의 3개 변수를 variable, value 의 2개 변수로 녹여서(melting) 재구조화함으로써, 옆으로 넓은 형태를 세로로 긴 형태 (wide to long)의 data.table로 재구조화 해보겠습니다. 



## -- 1. Melting data.tables (wide to long)

DT_melt_1 <- melt(DT, 

                  id.vars = c("Model", "Type", "DriveTrain"), 

                  measure.vars = c("Length", "Width", "Weight"))


## By default, the molten columns are automatically named 'variable' and 'value'.

print(DT_melt_1)

# Model    Type DriveTrain variable value

# 1: Integra   Small      Front   Length   177

# 2:  Legend Midsize      Front   Length   195

# 3:      90 Compact      Front   Length   180

# 4:     100 Midsize      Front   Length   193

# 5:    535i Midsize       Rear   Length   186

# 6: Integra   Small      Front    Width    68

# 7:  Legend Midsize      Front    Width    71

# 8:      90 Compact      Front    Width    67

# 9:     100 Midsize      Front    Width    70

# 10:    535i Midsize       Rear    Width    69

# 11: Integra   Small      Front   Weight  2705

# 12:  Legend Midsize      Front   Weight  3560

# 13:      90 Compact      Front   Weight  3375

# 14:     100 Midsize      Front   Weight  3405

# 15:    535i Midsize       Rear   Weight  3640


str(DT_melt_1)

# Classes 'data.table' and 'data.frame': 15 obs. of  5 variables:

#   $ Model     : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 49 56 9 1 6 ...

# $ Type      : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 4 3 1 3 3 ...

# $ DriveTrain: Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 2 2 3 ...

# $ variable  : Factor w/ 3 levels "Length","Width",..: 1 1 1 1 1 2 2 2 2 2 ...

# $ value     : int  177 195 180 193 186 68 71 67 70 69 ...

# - attr(*, ".internal.selfref")=<externalptr>




위의 str()함수로 각 변수의 데이터 형태를 보면 "variable" 변수는 요인형(Factor) 입니다. melt() 함수로 재구조화 시 "variable" 칼럼의 기본 설정값은 요인형(Factor) 인데요, 만약 요인형 말고 문자형(charactor) 으로 하고 싶다면 variable.factor = FALSE 로 매개변수를 설정해주면 됩니다. 



## By default, 'variable' column is of type factor. 

## Set variable.factor argument to FALSE if you like to return a character vector. 

DT_melt_2 <- melt(DT, 

                  id.vars = c("Model", "Type", "DriveTrain"), 

                  measure.vars = c("Length", "Width", "Weight"), 

                  variable.factor = FALSE)


str(DT_melt_2)

# Classes 'data.table' and 'data.frame': 15 obs. of  5 variables:

#   $ Model     : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 49 56 9 1 6 ...

# $ Type      : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 4 3 1 3 3 ...

# $ DriveTrain: Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 2 2 3 ...

# $ variable  : chr  "Length" "Length" "Length" "Length" ...  # <--- charactr vector

# $ value     : int  177 195 180 193 186 68 71 67 70 69 ...

# - attr(*, ".internal.selfref")=<externalptr>




만약 녹여서(melting) 길게(wide to long) 재구조화한 후의 "variable", "value" 변수 이름을 사용자가 지정해서 다른 이름으로 부여를 하고 싶다면 variable.name = "new_variable_name", value.name = "new_value_name" 처럼 매개변수에 새로운 칼럼 이름을 부여해주면 됩니다. 



## Name the 'variable' and 'value' columns to 'measure' and 'val' respectively.

DT_melt_3 <- melt(DT, 

                  id.vars = c("Model", "Type", "DriveTrain"), 

                  measures.vars = c("Length", "Width", "Weight"), 

                  variable.name = "measure"

                  value.name = "val")


head(DT_melt_3)

# Model    Type DriveTrain measure val

# 1: Integra   Small      Front  Length 177

# 2:  Legend Midsize      Front  Length 195

# 3:      90 Compact      Front  Length 180

# 4:     100 Midsize      Front  Length 193

# 5:    535i Midsize       Rear  Length 186

# 6: Integra   Small      Front   Width  68





  (2) dcast() : data.table 을 주조하여 긴 자료구조를 넓게 (long to wide) 재구조화


위의 (1)번에서 세로로 길게 재구조화한 data.table을 원래의 옆으로 넓은 형태로 역으로 재구조화를 하고 싶으면 dcast() 함수를 사용하면 됩니다. 


dcast(DT, ID1 + ID2 + ID3 ~ variable) 처럼 함수 형태의 구문을 사용합니다. 



## -- 2. dcasting data.tables (long to wide)

## reverse operation of melting

## dcast uses formula interface.

dcast(DT_melt_1, Model + Type + DriveTrain ~ variable)

# Model    Type DriveTrain Length Width Weight

# 1:     100 Midsize      Front    193    70   3405

# 2:    535i Midsize       Rear    186    69   3640

# 3:      90 Compact      Front    180    67   3375

# 4: Integra   Small      Front    177    68   2705

# 5:  Legend Midsize      Front    195    71   3560




만약 위의 (1)번에서 "variable"과 "value" 칼럼이름을 사용자가 지정해서 melt()를 수행했다면 dcast() 를 하여 역으로 넓게 재구조화하려고 할 때 사용자가 지정한 변수(variable)와 값(value)의 칼럼 이름을 사용해주면 됩니다. 


위의 (1-3) 예에서 만든 DT_melt_3 이름의 data.table을 dcast()로 재구조화하려면 

dcast(DT_melt_3, Model + Type + DriveTrain ~ measure, value.var = "val"

처럼 위 (1-3)에서 지정했던 변수(variable) 이름인 'measure', 값(value) 이름인 value.var = "val" 을 써주면 됩니다. 



## 'value.var' denotes the column to be filled in with while casting to wide format. 

dcast(DT_melt_3, Model + Type + DriveTrain ~ measure

      value.var = "val")

# Model    Type DriveTrain Length Width Weight

# 1:     100 Midsize      Front    193    70   3405

# 2:    535i Midsize       Rear    186    69   3640

# 3:      90 Compact      Front    180    67   3375

# 4: Integra   Small      Front    177    68   2705

# 5:  Legend Midsize      Front    195    71   3560

 



dcast() 함수에 집계함수(aggregation function)를 사용하여 ID 그룹별로 요약통계량을 계산한 결과를 재구조화하여 반환할 수도 있습니다.


위의 (1)에서 data.table을 길게 녹여서 재구조화했던 DT_melt_1에 대해서 차종(Type)을 기준으로 녹여서 만든 변수(variable)에 대해 평균(fun.aggregate = mean)을 집계하여 역으로 옆으로 넓게 재구조화한 data.table을 반환해보겠스니다. 



## You can pass a function to aggregate by in dcast with the argument 'fun.aggregate. 

dcast(DT_melt_1, Type ~ variable, fun.aggregate = mean)

# Type   Length Width Weight

# 1: Compact 180.0000    67   3375

# 2: Midsize 191.3333    70   3535

# 3:   Small 177.0000    68   2705




fun.aggregate 는 fun.agg 로 줄여서 쓸 수 있으며, fun.agg 뒤에는 function(x) 로 해서 어떠한 R 함수도 써줄 수 있습니다. 아래 예에서는 x가 결측값인지(1) 아닌지(0) 여부에 대해서 합(sum)을 구하는 집계함수로서 fun.agg = function(x) sum(!is.na(x)) 를 써주었습니다. (즉, 결측값이 아닌 행의 개수)


그리고 subset 매개변수를 사용하면 dcast()의 대상이 되는 data.table에서 특정 조건을 만족하는 부분집합만 필터링해와서 dcast() 재구조화를 할 수도 있습니다. 



## 'fun.agg' is the same with 'fun.aggregate'

## subset: Specified if casting should be done on a subset of the data.

dcast(DT_melt_1, Type ~ variable, 

      fun.agg = function(x) sum(!is.na(x))

      subset = .(variable != "Length"))

# Type Width Weight

# 1: Compact     1      1

# 2: Midsize     3      3

# 3:   Small     1      1



[Reference]

* R data.table vignette
: https://cran.r-project.org/web/packages/data.table/vignettes/datatable-reshape.html



다음번 포스팅에서는 특정 패턴이 있는 data.table의 러개 칼럼을 동시에 녹이고 주조하여 재구조화하는 방법을 소개하겠습니다. (https://rfriend.tistory.com/576)



이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요!



Posted by R Friend Rfriend

댓글을 달아 주세요

DB에 들어있는 데이터를 내렸을 때, 설문조사 데이터를 받았을 때, 원천 거래 데이터를 받았을 때, 혹은 분석 과정 중의 데이터 셋이 분석가가 하고자 하는 통계분석, 데이터마이닝 분석이나 ggplot2 등의 그래프/시각화를 위해 필요한 데이터 구조로 딱 맞아떨어지지 않는 경우가 굉장히 많습니다.

 

이때 필요한 것이 데이터를 분석 목적, 기법에 맞게 자유자재로 변형하여 재구조화하는 일입니다.  

 

엑셀에서 Pilvot Table 생성하는 것이 제일 이해하기 쉬운 예가 될거 같습니다.  세로로 길게 늘어서 있는 원 데이터를 가로와 세로로 틀을 잡아 주고, 가운데에는 value 값에 대해서 개수를 센다든지, 합계를 낸다든지, 평균을 구한다든지 하는 함수를 적용하는 것을 해보셨을 겁니다. 

 

비유를 해보자면, 레고블록으로 높이 세워진 탑을 모양과 색깔별로 레고 블록을 잘 분해한 다음에, 이를 재료로 해서 가로와 세로로 넓게 펴고 높이는 낮추어서 새로운 탑을 만드는 것이라고 생각해보는 것도 이해하는데 도움이 될거 같습니다.

 

이때 데이터 재구조화하는 기준 변수를 무엇으로 하느냐, 가로로 길게 늘어뜨릴 변수는 또 무엇으로 하느냐, 가운데에 값을 볼 때 무슨 함수를 사용해서 값을 계산해서 볼 것이냐에 따라서 다양한 경우의 수가 발생하게 됨에 따라 말로 모든 것을 설명하는 것이 무리가 있습니다.  따라서 아래에 reshape 패키지의 melt(), cast() 함수를 몇 가지 경우의 수에 적용해 보면서 원래 값이 이후에 어떻게 바뀌는지를 유심히 보시고, 필요한 상황에 맞는 R script를 참고하시면 되겠습니다.

 

 

[ reshape 패키지 내 melt()함수, cast() 함수 사용 데이터 재구조화 예시 ]

 

 

 

 

예제로 사용할 데이터는 MASS 패키지에 내장되어 있는 Cars93 데이터 프레임의 차종(Type), 제조국(Origin), 도시 연비(MPG.city), 고속도로 연비(MPG.highway) 4개의 변수를 사용해서 몇가지의 경우의 수를 조합해 가면서 데이터를 녹였다가 (melt) 재구조화 (cast) 를 해보겠습니다.

 

> library(MASS) > str(Cars93) 'data.frame': 93 obs. of 27 variables: $ Manufacturer : Factor w/ 32 levels "Acura","Audi",..: 1 1 2 2 3 4 4 4 4 5 ... $ Model : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 24 54 74 73 35 ... $ Type : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 3 2 2 3 2 ... $ Min.Price : num 12.9 29.2 25.9 30.8 23.7 14.2 19.9 22.6 26.3 33 ... $ Price : num 15.9 33.9 29.1 37.7 30 15.7 20.8 23.7 26.3 34.7 ... $ Max.Price : num 18.8 38.7 32.3 44.6 36.2 17.3 21.7 24.9 26.3 36.3 ... $ MPG.city : int 25 18 20 19 22 22 19 16 19 16 ... $ MPG.highway : int 31 25 26 26 30 31 28 25 27 25 ... $ AirBags : Factor w/ 3 levels "Driver & Passenger",..: 3 1 2 1 2 2 2 2 2 2 ... $ DriveTrain : Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 3 2 2 ... $ Cylinders : Factor w/ 6 levels "3","4","5","6",..: 2 4 4 4 2 2 4 4 4 5 ... $ EngineSize : num 1.8 3.2 2.8 2.8 3.5 2.2 3.8 5.7 3.8 4.9 ... $ Horsepower : int 140 200 172 172 208 110 170 180 170 200 ... $ RPM : int 6300 5500 5500 5500 5700 5200 4800 4000 4800 4100 ... $ Rev.per.mile : int 2890 2335 2280 2535 2545 2565 1570 1320 1690 1510 ... $ Man.trans.avail : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 1 1 ... $ Fuel.tank.capacity: num 13.2 18 16.9 21.1 21.1 16.4 18 23 18.8 18 ... $ Passengers : int 5 5 5 6 4 6 6 6 5 6 ... $ Length : int 177 195 180 193 186 189 200 216 198 206 ... $ Wheelbase : int 102 115 102 106 109 105 111 116 108 114 ... $ Width : int 68 71 67 70 69 69 74 78 73 73 ... $ Turn.circle : int 37 38 37 37 39 41 42 45 41 43 ... $ Rear.seat.room : num 26.5 30 28 31 27 28 30.5 30.5 26.5 35 ... $ Luggage.room : int 11 15 14 17 13 16 17 21 14 18 ... $ Weight : int 2705 3560 3375 3405 3640 2880 3470 4105 3495 3620 ... $ Origin : Factor w/ 2 levels "USA","non-USA": 2 2 2 2 2 1 1 1 1 1 ... $ Make : Factor w/ 93 levels "Acura Integra",..: 1 2 4 3 5 6 7 9 8 10 ...

 

 

데이터 양이 너무 많으면 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
> install.packages("reshape")

> 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
> 

 > # 두개의 id.var 기준(세로) & variable(가로) 조합의 value 값에 mean 함수 적용

> 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
> 

 > # 한개의 id.var 기준(세로) & 다른 id.var + variable (가로) 조합의 value 값에 mean 함수 적용

> 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
> 

 > # 한개의 id.var + variable (세로) & 다른 id.var (가로) 조합의 value 값에 mean 함수 적용

> 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

 > cast(data = Cars93_sample_melt, Origin + variable ~ Type, fun = mean)

   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

 


 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡' 단추를 꾸욱 눌러주세요.^^

 

Posted by R Friend Rfriend

댓글을 달아 주세요

  1. 빵먹어 2016.05.13 18:05  댓글주소  수정/삭제  댓글쓰기

    공부하는 데 많은 도움이 되어 제 블로그에 공유하였습니다.
    내용 변환없이, 그리고 원작자 출처 명확히 밝혔습니다.
    좋은 글 감사합니다.

    • R Friend Rfriend 2016.05.13 19:12 신고  댓글주소  수정/삭제

      블로그 포스팅의 부분 인용 & 출처 기입은 괜찮구요,

      그게 아니라 블로그 포스팅 통 스크랩일 경우는
      (1) 제목 & 링크,
      or (2) (개인학습 용도로) 비공개 전환,
      or (3) (개인학습 용도로) 즐겨찾기 추가를 해서
      이용하시기 바랍니다.

      네이버의 '스크랩' 같이 원본 그대로 옮겨 포스팅하는 경우(비록 출처를 밝혔다 하더라도) 외국 블로깅에서는 있을 수 없는 일이예요.

      제가 블로깅 하는 원칙이기도 하구요, 블로거들이 서로 지키는 예절이기도 합니다.

      이해해 주시기 바랍니다.

  2. AshtrayK 2016.09.28 09:56 신고  댓글주소  수정/삭제  댓글쓰기

    질문있어요~ 이글에 맞는지는 모르겠지만..
    칼럼1(id)에는 725284 , 칼럼2(keyword_count)에는 대출:4^출금:3^이자:2
    이런식의 데이터가 담겨 있습니다.
    칼럼2의 데이터는 id별 담겨있는키워드와 그 횟수인데요. 대출이라는 키워드가 4번 출금이라는 키워드 3번 나타나고 있다는 뜻입니다

  3. AshtrayK 2016.09.28 09:58 신고  댓글주소  수정/삭제  댓글쓰기

    이걸
    id, 키워드, 카운트 3개의 칼럼으로 해서 행하나에 키워드와 카운트를 한개씩만 들어가게하려면 어떻게해야할까요?

  4. AshtrayK 2016.09.28 09:59 신고  댓글주소  수정/삭제  댓글쓰기

    예를들어
    3301 대출 4
    3301 출금 3
    3301 이자 2

  5. AshtrayK 2016.09.28 10:00 신고  댓글주소  수정/삭제  댓글쓰기

    for문으로 만들어보긴했는데 원본의 1400여개 행을 작업해서 7만개 행으로 쪼개는데 20분이 드네요.. 너무오래걸려서 혹시 적절한 다른 방법이 있을까해서 질문드립니다~

    • R Friend Rfriend 2016.09.28 10:10 신고  댓글주소  수정/삭제

      (1) 2번째 칼럼 쪼개기
      (2) subset()으로 id, column(대출, 출금, 이자 별로 각 각), value(각 column 별 회수) 로 쌍으로 해서 칼럼 개수만큼 실행 (이 예제는 대출, 출금, 이자 3번)
      (3) rbind로 3개 데이터셋 합치기

      이렇게 한번 해보시지요.

  6. AshtrayK 2016.09.28 10:20 신고  댓글주소  수정/삭제  댓글쓰기

    (2)subset부분이 이해가 잘 안가는데요.. 음.. 이 데이터셋의 뜻은 각 콜당 핵심키워드의 빈도를 나타내는 거구요. 키워드의 종류 수는 제한이 없습니다. 즉 1행 2열에 들어가있는 키워드 종류가 대출 출금 이자 3가지라면 2행 2열에는 15가지일 수도 있습니다. 실제데이터에서 첫번째꺼는 46개구요.
    즉 2열의 한칸마다 데이터가 너무 길어서 보기 좋게하려고 키워드를 쪼개서 세로로 형태를 바꾸려고 하는거구요 ㅠㅠ

  7. 건영 2016.11.17 17:48  댓글주소  수정/삭제  댓글쓰기

    혼자 공부중인데 많은 도움받고 갑니당~

  8. Park_army 2020.06.18 20:42  댓글주소  수정/삭제  댓글쓰기

    안녕하세요!! 혹시 아까 오후에 질문 남겼었는데 확인해주시면 정말 감사하겠습니다ㅠㅠ