R을 이용한 데이터처리 & 분석실무 책을 참고로 합니다. 정확한 지식은 책을 통해 얻으시길 바랍니다

데이터 분석을 하면 항상 하는 것이 그룹 별로 분석을 적용하는 일입니다. tapply() 함수로도 해당 업무가 가능하지만, doBy package를 사용하는 것도 좋은 방법입니다.

doBy package에는 요약, 정렬, 샘플 추출 등의 일을 손쉽게 할 수 있습니다.

library(doBy)

1. summaryBy()

summaryBy() 함수는 데이터 내에서 원하는 컬럼의 값을 특정 조건에 따라 요약하는 목적으로 사용됩니다.

head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 
str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

iris 데이터는 5개의 컬럼으로 구서되어 있는데 species는 종을 나타내는 factor형 데이터고, 나머지는 측정값입니다. 그러면 species에 따라 width와 length 값을 요약 표시하고 싶다면 summaryBy() 함수를 활용합니다.

summaryBy(Sepal.Width + Sepal.Length ~ Species, data = iris)
##      Species Sepal.Width.mean Sepal.Length.mean
## 1     setosa            3.428             5.006
## 2 versicolor            2.770             5.936
## 3  virginica            2.974             6.588
summaryBy(Sepal.Width + Sepal.Length ~ Species, data = iris, FUN = "sd")
##      Species Sepal.Width."sd" Sepal.Length."sd"
## 1     setosa        0.3790644         0.3524897
## 2 versicolor        0.3137983         0.5161711
## 3  virginica        0.3224966         0.6358796

FUN의 default 값은 “mean” 입니다. 분산을 구하고 싶다면 “var”이라고 넣으면 됩니다.

2. orderBy

orderBy()는 데이터프레임을 정렬하는 목적으로 사용합니다. 앞서 order() 함수에 대해 잠시 살펴보면, order 함수는 주어진 값을 정렬하기 위한 색인을 순서대로 반환합니다.

order(iris$Sepal.Width)
##   [1]  61  63  69 120  42  54  88  94  58  81  82  70  73  90  99 107 109 114
##  [19] 147  80  91  93 119 135  60  68  83  84  95 102 112 124 143  55  56  72
##  [37]  74  77 100 115 122 123 127 129 131 133 134   9  59  64  65  75  79  97
##  [55]  98 104 108   2  13  14  26  39  46  62  67  76  78  85  89  92  96 103
##  [73] 105 106 113 117 128 130 136 139 146 148 150   4  10  31  35  53  66  87
##  [91] 138 140 141 142   3  30  36  43  48  51  52  71 111 116 121 126 144  24
## [109]  50  57 101 125 145   7   8  12  21  25  27  29  32  40  86 137 149   1
## [127]  18  28  37  41  44   5  23  38 110  11  22  49  19  20  45  47 118 132
## [145]   6  17  15  33  34  16
iris[c(61, 63), ]
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 61            5         2.0          3.5           1 versicolor
## 63            6         2.2          4.0           1 versicolor

Width 기준으로 iris를 정렬하면 61행이 가장 처음, 63행이 두 번째에 해당하는 식입니다. 오름차순으로 정렬됩니다.

이 순서대로 각행에 대한 색인으로 사용하면 정렬된 전체 테이블을 구할 수 있습니다.

head(iris[order(iris$Sepal.Width), ])
##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 61           5.0         2.0          3.5         1.0 versicolor
## 63           6.0         2.2          4.0         1.0 versicolor
## 69           6.2         2.2          4.5         1.5 versicolor
## 120          6.0         2.2          5.0         1.5  virginica
## 42           4.5         2.3          1.3         0.3     setosa
## 54           5.5         2.3          4.0         1.3 versicolor

Width의 오름차순으로 정렬된 것을 확인할 수 있습니다.

head(iris[order(iris$Sepal.Length, iris$Sepal.Width), ])
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 14          4.3         3.0          1.1         0.1  setosa
## 9           4.4         2.9          1.4         0.2  setosa
## 39          4.4         3.0          1.3         0.2  setosa
## 43          4.4         3.2          1.3         0.2  setosa
## 42          4.5         2.3          1.3         0.3  setosa
## 4           4.6         3.1          1.5         0.2  setosa

Length -> Width 순으로 오름차순으로 정렬됩니다.

이것을 orderBy()를 쓰면 조금 더 보기좋게 코딩할 수 있습니다.

head(orderBy(~ Sepal.Length + Sepal.Width, data = iris))
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 14          4.3         3.0          1.1         0.1  setosa
## 9           4.4         2.9          1.4         0.2  setosa
## 39          4.4         3.0          1.3         0.2  setosa
## 43          4.4         3.2          1.3         0.2  setosa
## 42          4.5         2.3          1.3         0.3  setosa
## 4           4.6         3.1          1.5         0.2  setosa

order가 기본 함수이기 때문에 자주 사용되기는 하나 단순히 그룹화가 목적이라면 orderBy()를 쓰는 것도 좋습니다.

3. sampleBy()

sampleBy()는 데이터를 그룹으로 묶은 후 각 그룹에서 샘플을 추출하는 함수입니다. R에 내장된 유사한 함수로는 sample()이 있습니다.

sample()함수는 기본값이 비복원추출입니다. 복원추출을 할 경우 replace = T를 넣어주어야 합니다.

sample(1:10, 5)
## [1] 10  2  1  8  3
sample(1:10, 5, replace = T)
## [1] 3 5 9 4 3

sample()함수는 랜덤으로 그룹을 섞을 때도 쓰입니다.

sample(1:10, 10)
##  [1]  3  1  8  2  7  9  4  6 10  5
head(iris[sample(NROW(iris), NROW(iris)), ])
##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 73           6.3         2.5          4.9         1.5 versicolor
## 64           6.1         2.9          4.7         1.4 versicolor
## 51           7.0         3.2          4.7         1.4 versicolor
## 81           5.5         2.4          3.8         1.1 versicolor
## 128          6.1         3.0          4.9         1.8  virginica
## 27           5.0         3.4          1.6         0.4     setosa

샘플링은 주로 주어진 데이터를 훈련 데이터와 검정 데이터로 분리할 때 사용됩니다.

sampleBy()를 사용한 예를 보겠습니다.

sampleBy(~ Species, frac = 0.1, data = iris)
##               Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## setosa.1               5.1         3.5          1.4         0.2     setosa
## setosa.17              5.4         3.9          1.3         0.4     setosa
## setosa.22              5.1         3.7          1.5         0.4     setosa
## setosa.23              4.6         3.6          1.0         0.2     setosa
## setosa.38              4.9         3.6          1.4         0.1     setosa
## versicolor.58          4.9         2.4          3.3         1.0 versicolor
## versicolor.62          5.9         3.0          4.2         1.5 versicolor
## versicolor.77          6.8         2.8          4.8         1.4 versicolor
## versicolor.88          6.3         2.3          4.4         1.3 versicolor
## versicolor.96          5.7         3.0          4.2         1.2 versicolor
## virginica.104          6.3         2.9          5.6         1.8  virginica
## virginica.111          6.5         3.2          5.1         2.0  virginica
## virginica.114          5.7         2.5          5.0         2.0  virginica
## virginica.134          6.3         2.8          5.1         1.5  virginica
## virginica.145          6.7         3.3          5.7         2.5  virginica
# frac은 데이터의 몇 %를 샘플링 할 지 정하는 것입니다.

doBy() package는 R에 내장된 summary(), order(), sample() 함수를 보다 쉽게 접근하도록 해줍니다.