Barplot(막대 그래프)

ggplot을 이용해 간단하게 막대그래프를 그리는 방법을 알아보겠습니다. 이 데이터는 회사의 부서별로 사람들이 회사에 대한 평가를 내린 데이터 셋 입니다. 우선 데이터에대한 탐색을 먼저 해보겠습니다.

setwd("C:\\Users\\chanb\\rpubs")


library(ggplot2)
library(sampling)
library(plyr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:plyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
data<-read.csv("HR_comma_sep.csv")
str(data)
## 'data.frame':    14999 obs. of  10 variables:
##  $ satisfaction_level   : num  0.38 0.8 0.11 0.72 0.37 0.41 0.1 0.92 0.89 0.42 ...
##  $ last_evaluation      : num  0.53 0.86 0.88 0.87 0.52 0.5 0.77 0.85 1 0.53 ...
##  $ number_project       : int  2 5 7 5 2 2 6 5 5 2 ...
##  $ average_montly_hours : int  157 262 272 223 159 153 247 259 224 142 ...
##  $ time_spend_company   : int  3 6 4 5 3 3 4 5 5 3 ...
##  $ Work_accident        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ left                 : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ promotion_last_5years: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ sales                : Factor w/ 10 levels "accounting","hr",..: 8 8 8 8 8 8 8 8 8 8 ...
##  $ salary               : Factor w/ 3 levels "high","low","medium": 2 3 3 2 2 2 2 2 2 2 ...
summary(data)
##  satisfaction_level last_evaluation  number_project  average_montly_hours
##  Min.   :0.0900     Min.   :0.3600   Min.   :2.000   Min.   : 96.0       
##  1st Qu.:0.4400     1st Qu.:0.5600   1st Qu.:3.000   1st Qu.:156.0       
##  Median :0.6400     Median :0.7200   Median :4.000   Median :200.0       
##  Mean   :0.6128     Mean   :0.7161   Mean   :3.803   Mean   :201.1       
##  3rd Qu.:0.8200     3rd Qu.:0.8700   3rd Qu.:5.000   3rd Qu.:245.0       
##  Max.   :1.0000     Max.   :1.0000   Max.   :7.000   Max.   :310.0       
##                                                                          
##  time_spend_company Work_accident         left       
##  Min.   : 2.000     Min.   :0.0000   Min.   :0.0000  
##  1st Qu.: 3.000     1st Qu.:0.0000   1st Qu.:0.0000  
##  Median : 3.000     Median :0.0000   Median :0.0000  
##  Mean   : 3.498     Mean   :0.1446   Mean   :0.2381  
##  3rd Qu.: 4.000     3rd Qu.:0.0000   3rd Qu.:0.0000  
##  Max.   :10.000     Max.   :1.0000   Max.   :1.0000  
##                                                      
##  promotion_last_5years         sales         salary    
##  Min.   :0.00000       sales      :4140   high  :1237  
##  1st Qu.:0.00000       technical  :2720   low   :7316  
##  Median :0.00000       support    :2229   medium:6446  
##  Mean   :0.02127       IT         :1227                
##  3rd Qu.:0.00000       product_mng: 902                
##  Max.   :1.00000       marketing  : 858                
##                        (Other)    :2923
summary(data$time_spend_company)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   2.000   3.000   3.000   3.498   4.000  10.000
table(data$sales)
## 
##  accounting          hr          IT  management   marketing product_mng 
##         767         739        1227         630         858         902 
##       RandD       sales     support   technical 
##         787        4140        2229        2720

Sampling strata

부서별로 데이터 셋의 수가 다름을 알 수가 있습니다. 따라서 ’sales’변수에 10개의 명목형 변수가 있기에 500개씩 데이터를 층화추출 해보겠습니다.추출된 데이터의 id를 이용하여 새로운 데이터를 만들겠습니다.

set.seed(12345)
data.sample.index <- strata(data = data,
                                      stratanames = "sales",      # 층화로 사용되는 변수명,
                                      size = rep(500,each=10),    # 10개의 그룹에서 각각 10개
                                      method = "srswor")          # simple random sampling without replacement

data<-getdata(data,data.sample.index)

우리는 부서별로 회사에서 한달동안 보내는 시간을 알고싶다.즉 제일 많이 일하는 부서를 알고싶다. 여기서 “stat=‘identity’”를 지정하는 이유를 알아야 합니다. geom_bar는 기본적으로 “stat=‘bin’”을 설정합니다. 이 뜻은 ’도수’를 기준으로 y축을 설정하겠다는 뜻입니다. “stat=‘identity’”를 설정하면 average_montly_hours의 ’값’을 이용하겠다는 뜻입니다.

ggplot(data,aes(x=sales,y=average_montly_hours))+geom_bar(stat="identity")

순서가 이쁘지 않아서 순서대로 정렬하겠습니다. 이 때 reorder함수를 이용합니다. 또한 데이터의 변수가 많아질때는 x축에 변수이름을 두기보다는 y축에 변수를 넣으면 변수명을 보기가 더 좋습니다. 이때는 ’coord_flip()’함수를 이용합니다.

graph<-ggplot(data,aes(x=reorder(sales,average_montly_hours),y=average_montly_hours))+geom_bar(stat="identity",aes(fill=sales))
graph

graph+coord_flip()

막대의 넓이도 바꿀 수가 있습니다. ’width’함수를 이용합니다.

ggplot(data,aes(x=reorder(sales,average_montly_hours),y=average_montly_hours,fill=sales))+
  geom_bar(stat="identity",width=.5)

또한 보고싶은 부서만 볼 수 있습니다. 한달 평균 근무시간이 제일 많은 IT부서와 제일 적은 product_mng의 변수만 보겠습니다. ’scale_x_discrete()’함수를 이용합니다.

#Choose which items to display 
ggplot(data,aes(x=reorder(sales,average_montly_hours),y=average_montly_hours,fill=sales))+
  geom_bar(stat="identity",width=.5)+
  scale_x_discrete(limits=c("IT","product_mng"))
## Warning: Removed 4000 rows containing missing values (position_stack).

barplot with label

barplot에 label을 지정할때는 geom_text()함수를 이용합니다. 주로 빈도수를 표현할때 사용됩니다. position=position_stack(0.5) 각 막대 그래프에 중앙에 위치하게 정해줍니다. 0.9로 설정해주면 맨 위쪽에 설정되는 모습을 볼 수 있습니다.

ggplot(data,aes(x=factor(sales),fill=factor(salary)))+
  geom_bar()+
  geom_text(aes(label=..count..),stat="count",position=position_stack(0.5))

dodge옵션을 이용해 factor별로 따로 볼 수 있다. position=position_dodge(0.9)로 설정해줘야만 위치가 제대로 나타납니다.

ggplot(data,aes(x=factor(sales),fill=factor(salary)))+
  geom_bar(position="dodge")

ggplot(data,aes(x=factor(sales),fill=factor(salary)))+
  geom_bar(position="dodge")+
  geom_text(aes(label=..count..),stat='count',position=position_dodge(0.9))

##Proportional stacked bar plot fill옵션을 이용해 비율을 이용해 구할 수 있다.

ggplot(data,aes(x=factor(sales),fill=factor(salary)))+
  geom_bar(position="fill")

ggplot(data,aes(x=factor(sales),fill=factor(salary)))+
  geom_bar(position="fill")+
  geom_text(aes(label=..count..),stat='count',position=position_fill(vjust=0.5))

ggplot(data,aes(x=factor(sales),fill=factor(salary)))+
  geom_bar(position="fill")+
  geom_text(aes(label=scales::percent(..count../sum(..count..))),
            stat='count',position=position_fill(vjust=0.5))

Barplot with errorbar

이번에는 회사에서 보내는 시간을 기준으로 pivot table을 만들어 보겠습니다.

df1=ddply(data,c("sales","salary"),summarise,mean=mean(time_spend_company),sd=sd(time_spend_company),n=length(time_spend_company),se=sd/sqrt(n))
## Warning: package 'bindrcpp' was built under R version 3.4.1
colnames(df1)[3]="time_spend_money"
df1
##          sales salary time_spend_money        sd   n         se
## 1   accounting   high         3.142857 1.3537919  42 0.20889463
## 2   accounting    low         3.438017 1.1905057 242 0.07652861
## 3   accounting medium         3.671296 1.6391462 216 0.11152977
## 4           hr   high         2.766667 0.7738544  30 0.14128583
## 5           hr    low         3.226891 0.9802865 238 0.06354254
## 6           hr medium         3.508621 1.2552621 232 0.08241199
## 7           IT   high         3.027778 0.9996031  36 0.16660052
## 8           IT    low         3.425197 1.2288990 254 0.07710798
## 9           IT medium         3.500000 1.5256970 210 0.10528309
## 10  management   high         4.942197 2.8908657 173 0.21978845
## 11  management    low         3.481203 1.4491455 133 0.12565685
## 12  management medium         4.123711 2.0825340 194 0.14951723
## 13   marketing   high         3.512821 1.6681505  39 0.26711786
## 14   marketing    low         3.593220 1.5668768 236 0.10199499
## 15   marketing medium         3.564444 1.6384274 225 0.10922850
## 16 product_mng   high         3.416667 1.5000000  36 0.25000000
## 17 product_mng    low         3.311024 1.2580635 254 0.07893793
## 18 product_mng medium         3.380952 1.1971334 210 0.08261005
## 19       RandD   high         3.406250 1.4560081  32 0.25738831
## 20       RandD    low         3.354701 1.2661995 234 0.08277405
## 21       RandD medium         3.320513 1.1174802 234 0.07305197
## 22       sales   high         3.714286 1.8875977  35 0.31906225
## 23       sales    low         3.369478 1.3013765 249 0.08247138
## 24       sales medium         3.606481 1.6418239 216 0.11171197
## 25     support   high         3.342857 1.6259451  35 0.27483488
## 26     support    low         3.616279 1.4073344 258 0.08761681
## 27     support medium         3.371981 1.4686985 207 0.10208160
## 28   technical   high         3.515152 1.4815788  33 0.25790977
## 29   technical    low         3.478927 1.1720037 261 0.07254521
## 30   technical medium         3.490291 1.3497616 206 0.09404235
p<-ggplot(df1,aes(x=sales,y=time_spend_money,fill=salary))
p+geom_bar(stat="identity")

p1=p+geom_bar(stat="identity",position="dodge")+
  geom_errorbar(aes(ymin=time_spend_money-se,ymax=time_spend_money+se),
                position="dodge",width=0.2)
p1

error의 위치가 이상해 position=position_dodge(0.9)을 이용 했습니다.

p2=p+geom_bar(stat="identity",position="dodge")+
  geom_errorbar(aes(ymin=time_spend_money-se,ymax=time_spend_money+se), position=position_dodge(0.9),width=0.2)

p2

#Barplot with color 기본적으로 ’scale_fill_manual’함수를 이용하면 직접 색깔을 지정해야한다는 특징이 있고 ’scale_fill_brewer’을 이용하면 연속된 색깔로 알아서 지정해줍니다.

p2+scale_fill_brewer(palette="Paired") + theme_minimal()

p2+ labs(title="Barplot of time_spend_money", 
         x="Sales", y = "time_spend_money")+
  scale_fill_manual(values=c('black','lightgray',"darkgray"))+
  theme_classic()

# Greens
p2 + scale_fill_brewer(palette="Greens") + theme_minimal()

# Reds
p2 + scale_fill_brewer(palette="Reds") + theme_minimal()