그룹 요약 통계집계함수 aggregate, tapply 병렬 최소최대값 pmin,pmax 2020년 , 2021년 20 대 대기업 연봉 변동

  그룹 요약 집계 함수는  대부분 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

댓글 없음:

댓글 쓰기

css cheat sheet 클래스 선택자, margin(마진), display , center 조정 간단한 구성 요소

 앞에서는 html의 간단한 sheet를 소개 하였습니다.   html은  주로 골격을 나타나는 것이라, 디자인을 하는데는 css로 하여야 합니다.  아래 코드와 같이 css 관련 하여 매우 간단하게 코딩 하겠습니다.  body 부분의 css 코딩  ...