그룹 요약 집계 함수는 대부분 dplyr의 group_by(변수명), summarise() 연산 할 수 있다. 하지만, 우리가 데이터를 분석하기 전에, 미리 간단하게 내용을 보고자 할 때는, Rbase 함수가 보다 간단하게 쓰일 경우가 있다. 20대 대기업 연봉 변동도, 아래 예제와 같이 aggregate, tapply 함수 ggplot2 그래프롤 그리면, 여러가지 인사이트를 얻을 수 있다.
2.8.2 그룹 요약 통계를 위한 집계함수
y와 z의 평균 또는 분산과 같은 요약 함수에 사용하기 위한 반응변수(y와 z)와 설명 변수(x와 w)가 있다고 가정합시다. aggregate 함수는 다음과 같이 4종류의 요약값을 계산 할수 있는 수식 형태 입니다.
- 일대일 : aggregate(y ~ x, mean)
- 일대다 : aggregate(y ~ x + w, mean)
- 다대일 : aggregate(cbind(y,z) ~ x, mean)
- 다대다 : aggregate(cbind(y,z) ~ x + w, mean)
이러한 수식 형태는 데이터 프레임에서 인의적 반복을 제거하여 계산 하는데, 매우 유용합니다. 2개의 연속형 변수(Growth.rate와 ph)와 3개의 범주형 설명 변수(Water, Detergent,Daphnia)로 구성된 데이터 프레임 예제를 봅시다.
data <- read.table("PHDaphnia.txt", header = T)
names(data)
## [1] "Growth.rate" "Water" "Detergent" "Daphnia" "pH"
다음은 2개의 물 표본하에서 평균성장률을 알아내기 위해 aggregate 함수를 사용한 예제 입니다.
aggregate(Growth.rate ~ Water, data, mean)
## Water Growth.rate
## 1 Tyne 3.685862
## 2 Wear 4.017948
다음은 물과 세제 사이의 상호 작용을 볼 수 있는 일대다 수식의 연산 예제 입니다.
aggregate(Growth.rate ~ Water + Detergent, data, mean)
## Water Detergent Growth.rate
## 1 Tyne BrandA 3.661807
## 2 Wear BrandA 4.107857
## 3 Tyne BrandB 3.911116
## 4 Wear BrandB 4.108972
## 5 Tyne BrandC 3.814321
## 6 Wear BrandC 4.094704
## 7 Tyne BrandD 3.356203
## 8 Wear BrandD 3.760259
물(Water)과 세제(Detergent)의 교호작용에 대한 평균 PH와 평균 Growth.rate를 알아내기 위한 다대다 적용 사례 입니다.
aggregate(cbind(pH,Growth.rate)~ Water + Detergent, data, mean)
## Water Detergent pH Growth.rate
## 1 Tyne BrandA 4.883908 3.661807
## 2 Wear BrandA 5.054835 4.107857
## 3 Tyne BrandB 5.043797 3.911116
## 4 Wear BrandB 4.892346 4.108972
## 5 Tyne BrandC 4.847069 3.814321
## 6 Wear BrandC 4.912128 4.094704
## 7 Tyne BrandD 4.809144 3.356203
## 8 Wear BrandD 5.097039 3.760259
2.8.3 P 병렬 최소값과 최대값 : pmin과 pmax
다음과 같은 길이를 갖는 x,y,z 벡터입니다. 병렬 최소 함수 pmin은 각 첨자의 세가지 변수 중 1개에서 최소값을 찾아, 그 결과 x,y,z에 가장 긴 길이를 갖는 벡터의 동일한 길이의 벡터를 생성 합니다. ’
# 벡터를 만든다.
x <- c(0.99822644, 0.98204599, 0.20206455, 0.65995552, 0.93456667, 0.18836278)
y <- c(0.51827913, 0.30125005, 0.41676059, 0.53641449, 0.07878714, 0.49959328)
z <- c(0.26591817, 0.13271847, 0.44062782, 0.65120395, 0.03183403, 0.36938092)
pmin(x,y,z)
## [1] 0.26591817 0.13271847 0.20206455 0.53641449 0.03183403 0.18836278
따라서 첫번째와 두 번째 최소값은 z 에서, 세번째는 x에서 , 네번째는 y에서, 다섯번째는 z에서, 여섯번째는 x에서 나옵니다. min과 max 함수는 결과값으로 스칼라가 아닌 벡터를 생성 합니다.
스칼라, 벡터 그리고 매트릭스는 아래와 그림과 같이 정의 합니다.
스칼라, 벡터, 매트릭스 표1 |
2.8.4 그룹별 벡터 요약 정보
벡터 함수 tapply는 알고 있어야 하는 가장 중요하고 유용한 벡터 함수입니다. 't'
는 table을 의미하고 하나 이상의 그룹 변수를 이용해 벡터 값을 테이블로 만드는 함수를 말합니다. 실제 사용사례는 아래와 같습니다.
setwd("~/Dropbox/01.R분석/01.자율교육/2022년 자율교육/3강")
data <- read.table("daphnia.txt", header = T)
attach(data)
names(data)
## [1] "Growth.rate" "Water" "Detergent" "Daphnia"
반응변수는 Growth.rate이고 나머지 다른 3개의 변수는 요인 factor입니다. 각 세제의 평균 성장률을 계산하면 다음과 같습니다.
tapply(Growth.rate, Detergent, mean)
## BrandA BrandB BrandC BrandD
## 3.884832 4.010044 3.954512 3.558231
예제를 실행 하면 세제(Detergent)의 각 수순에 대한 성장률 테이블을 생성 합니다. 2개의 그룹 변수를 리스트에 넣으면 이차원 테이블을 만드는데 사용됩니다. 예를 들어 물 종류 와 물벼록 복제에 대한 중위수 성장률을 계산 합니다.
tapply(Growth.rate, list(Water, Daphnia), median)
## Clone1 Clone2 Clone3
## Tyne 2.874053 3.908644 4.618288
## Wear 2.590373 5.532726 4.302642
리스트의 첫번째 변수는 테이블의 행을, 두 번째 변수를 열을 만듭니다.
2.8.5 벡터 내에서 주소
함수 which는 벡터 내에서 데이터의 위치를 찾기 위한 함수 입니다. 다음과 같은 벡터 y가 있습니다.
y<-c(8,3,5,7,6,6,8,9,2,3,9,4,10,4,11)
y의 값 중에서 5보다 큰값을 갖는 데이터를 구합니다. 이를 위해서 다음과 같은 명령을 실행 합니다.
which(y>5)
## [1] 1 4 5 6 7 8 11 13 15
실행 결과는 벡터 내에서 해당 값의 위치를 위하하는 첨자가 됩니다. which 함수는 배열 전체를 대상으로 적용하므로 첨자를 사용하지 않습니다. 값 5를 초과 하는 y값을 구하려면 다음 명령어을 실행 해야 합니다.
y[y>5]
## [1] 8 7 6 6 8 9 9 10 11
계산 결과 5이하의 값은 생략 되었기 때문에 벡터의 길이가 y 벡터 보다 잛습니다.
length(y)
## [1] 15
length(y[y>5])
## [1] 9
2.8.6 가장 가까운 값 검색
설정된 값에 가장 가까운 벡터값을 찾으려면 간단히 which 함수를 사용합니다.벡터 xv는 평균 100과 표준편차 10인 모수를 갖는 정규분포에서 추출한 1000의 난수입니다.
set.seed(1004) # 난수의 값을 고정 시켜주는 역할을 함
xv <- rnorm(1000,100,10)
# 난수 그래프
plot(xv, type="l", col="#DC143C")
난수 그래프 |
# 확률밀도 그림을 넣어 정규분포의 그래프를 그린다.
plot(density(xv), type="l", col="#DC143C")
정규분포 그래프 |
108.0에 가장 가까운 값은 xv 값을 찾으려면 108과 1000개의 임의 숫자에 대해 차이를 계산 하고, 가장 작은 차이를 갖는 값을 찾아내야 합니다. 이러한 연산을 위한 R명령은 다음과 같습니다.
which(abs(xv-108) == min(abs(xv-108)))
## [1] 385
108.0에 가장 가까운 값은 xv 벡터에서 385번째 값이라는 것을 알 수 있습니다. 하지만 385번째 값을 108.0에 얼마나 근접해 있는지를 알아내야 하는 경우가 있으며, 이를 위해 벡터 xv 벡터에 첨자 385를 사용합니다.
xv[385]
## [1] 107.9676
다음과 같이 모든 벡터(xv)에 설정된 값(sv)에 가장 근사한 값을 계산하는 기능을 함수로 작성하면 다음과 같습니다.
closest <- function(xv, sv){
xv[which(abs(xv-sv) == min(abs(xv-sv)))]
}
실행 결과는 다음과 같습니다.
closest(xv,108)
## [1] 107.9676
예제 1
한국경제 2022.04.24 '억' 소리나는 대기업 연봉 인플레... 근로자 평균의 4배 올랐다.
의 기사 내용을 참고 하여, 전체 평균연봉, 업종별 평균, 연도별 평균 연봉과 인상률을 구하여라. 데이터를 집계할때는 tapply 함수를 이용한다.
대기업 연봉 변화 표 |
# 연봉 데이터 셋을 읽어 온다.
library(readxl)
library(dplyr)
##
## 다음의 패키지를 부착합니다: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
Salary <- read_excel("Salary.xlsx")
head(Salary)
## # A tibble: 6 × 5
## 시총순위 업종 회사명 yr2020 yr2021
## <dbl> <chr> <chr> <dbl> <dbl>
## 1 1 반도체 삼성전자 12700 14400
## 2 2 화학 LG에너지솔루션 8300 9000
## 3 3 반도체 SK하이닉스 9358 11500
## 4 4 IT 네이버 10248 12915
## 5 5 생명과학 삼성바이오로직스 8300 7900
## 6 6 IT 카카오 10800 17200
dplyr
패키지를 이용해서, 증감율을 구해 봅니다.
Salary <- Salary %>% mutate(증감율 = round((yr2021 - yr2020)/yr2020,2))
tapply()
함수를 이용해서 업종별 평균연봉을 구합니다.
# 2020 업종별 평균
tapply(Salary$yr2020, Salary$업종, mean)
## 금융 무역 반도체 생명과학 자동차 전자 철강 화학
## 12466.67 9800.00 10119.33 8000.00 8900.00 8600.00 9800.00 9300.00
## IT
## 10524.00
#2021년 업종별 평균
tapply(Salary$yr2021, Salary$업종, mean)
## 금융 무역 반도체 생명과학 자동차 전자 철강 화학
## 14166.667 11000.000 12300.000 7850.000 9833.333 9700.000 10900.000 9884.000
## IT
## 15057.500
업종별 년도별로 구하기 위해, 데이터셋 구조를 바꾸어 줍니다.
# 데이터를 분석 할수 있는 데이터셋으로 구조를 바꾼다.
library(tidyr)
library(dplyr)
Salary <- Salary %>% gather(년도,연봉 , -시총순위, -업종, -회사명, - 증감율)
attach(Salary)
head(Salary)
## # A tibble: 6 × 6
## 시총순위 업종 회사명 증감율 년도 연봉
## <dbl> <chr> <chr> <dbl> <chr> <dbl>
## 1 1 반도체 삼성전자 0.13 yr2020 12700
## 2 2 화학 LG에너지솔루션 0.08 yr2020 8300
## 3 3 반도체 SK하이닉스 0.23 yr2020 9358
## 4 4 IT 네이버 0.26 yr2020 10248
## 5 5 생명과학 삼성바이오로직스 -0.05 yr2020 8300
## 6 6 IT 카카오 0.59 yr2020 10800
업종 년도별로, 평균 연봉을 구합니다.
round(tapply(연봉, list(업종, 년도), mean))
## yr2020 yr2021
## 금융 12467 14167
## 무역 9800 11000
## 반도체 10119 12300
## 생명과학 8000 7850
## 자동차 8900 9833
## 전자 8600 9700
## 철강 9800 10900
## 화학 9300 9884
## IT 10524 15058
년도 별 평균연봉을 구합니다.
tapply(연봉, 년도, mean)
## yr2020 yr2021
## 9870.30 11348.35
어느 업종이 연봉의 변동이 많았는지 시각화 해 봅시다.
library(ggplot2)
Salary %>%
group_by(년도, 업종) %>%
summarise(연봉 = mean(연봉)) %>%
ggplot(aes(년도,연봉, fill = 년도)) +
geom_bar(stat = "identity") +
facet_wrap(~업종, nrow =2)
## `summarise()` has grouped output by '년도'. You can override using the
## `.groups` argument.
20대 대기업 년도별 연봉변화 |
위 그래프를 보면 IT
분야의 연봉 약진이 보입니다.
aggregate 가지고 년도별 변화량을 볼수 있습니다.
aggregate(연봉 ~ 년도 , Salary, mean)
## 년도 연봉
## 1 yr2020 9870.30
## 2 yr2021 11348.35
댓글 없음:
댓글 쓰기