11.1 히스토그램
히스토그램(Histogram)은 한 개의 연속형 변수를 일정한 구간 폭(binwidth)을 갖는 구간(bin)으로 분할하여, 각 구간의 빈도수를 막대 그래프로 시각화한 것입니다.
11.1.1 데이터 세트
이번 절에서는 먼저 ggplot2
패키지의 geom_histogram()
를 활용해서 히스토그램을 그리는 방법에 대해서 알아보겠습니다.
데이터는 MASS
패키지에 들어있는 Cars93
데이터 프레임 데이터 세트에서 가격(Price
)과 자동차유형(Type
) 변수를 활용하여 히스토그램을 그려보겠습니다.
library(ggplot2) # 또는 library(tidyverse)
# Cars93 데이터 프레임
library(MASS)
str(Cars93)
11.1.2 기본 히스토그램
ggplot2
패키지를 library()
로 호출한 후에 ggplot()
함수의 + geom_histogram()
함수를 사용하여 기본 값 옵션으로 히스토그램을 그리면 됩니다.
히스토그램을 그리는 기본적인 절차는 다음과 같습니다.
ggplot(Cars93, aes(x = Price))
:Cars93
을 데이터 세트로 사용하며,aes( )
함수 안에 x 축에 표시할 변수로Price
를 지정해 줍니다. 이ggplot()
함수로 기본 그래프를 작성하지만 아무런 결과도 표시가 되지 않습니다.+
: 기본 그래프와 다음에 나올 그래프 관련 함수들을 연결해 줍니다.geom_histogram()
: 기본 그래프를 히스토그램 형태로 시각화 해줍니다.
이제 Cars93
데이터 세트에서 가격(Price
) 변수를 기본적인 히스토그램으로 시각화해 보겠습니다.
# binwidth defaulted to range/30
ggplot(Cars93, aes(x = Price)) + # 그래프의 기본 틀을 설정합니다. 데이터와 X축의 변수를 지정합니다.
geom_histogram() # 히스트로그램으로 표현합니다.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot()
함수에 대한 자세한 사항은 ? ggplot
을 참고하기 바랍니다.
11.1.3 구간 폭의 기본값
위에 실행결과 콘솔창의 메시지를 보면 “stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
”이라는 메시지가 아래 보이는데요, 이는 binwidth
를 설정하지 않아서 range/30
디폴트 기준으로 binwidth
를 계산해서 그렸다는 뜻입니다. 구간의 갯수(bins
)는 기본 값이 30개입니다.
아래에 실제 범위(range
)를 구해서 30으로 나누었더니 1.816 이었고, 이 값을 geom_histogram(binwidth = 1.816)
옵션값으로 입력해서 히스토그램을 그려보았더니 위와 같음을 알 수 있습니다.
library(MASS)
range(Cars93$Price) # Price 변수의 범위를 구합니다. (최솟값, 최댓값)
## [1] 7.4 61.9
diff(range(Cars93$Price)) # (최댓값 - 최솟값) 을 구합니다.
## [1] 54
diff(range(Cars93$Price))/30 # (최댓값 - 최솟값) / 30 을 구합니다. = 1.816
## [1] 1.8
ggplot(Cars93, aes(x=Price)) + # 그래프의 기본 틀을 설정합니다. 데이터와 X축을 지정합니다.
geom_histogram(binwidth = 1.816) + # 앞에서 구한 1,816을 구간의 폭으로 지정합니다.
ggtitle("Binwidth=1.816 ; Default, range/30")
11.1.4 구간의 폭 조정
히스토그램에서 중요하면서 어려운 문제 중의 하나가 bin
개수를 몇 개로 할 것인가, 다른 말로 binwidth
로 구간의 폭을 얼마로 할 것인가 입니다.
bin
개수가 너무 많으면 (즉, binwidth
가 너무 좁으면) 이빨빠진 머리빗처럼 데이터의 분포 모양을 파악하는데 부적절할 수가 있습니다. 반면에 bin
개수가 너무 적으면 (즉, binwidth
가 너무 넓으면) 너무 많은 도수가 하나의 bin
에 몰려서 막대기둥 한 두개만 덩그라니 서 있게 되어 이 또한 데이터의 분포 모양을 파악하는데 도움이 안되게 됩니다.
적절한 bin
개수를 선정하는게 중요합니다. 아래에서는 binwidth
값을 조절해 가면서 히스토그램을 그려보겠습니다.
그런데 여기서
ggplot()
함수의 결과를h1
과 같이 변수에 치환할 수 있습니다. 그리고h1
을 입력하면 바로 그래프가 출력되게 됩니다.
library(MASS)
# 다양한 폭으로 히스토그램 그리기
<- ggplot(Cars93, aes(x=Price)) +
h1 geom_histogram(binwidth = 0.5) + # 구간의 폭을 0.5로 설정합니다.
ggtitle("Binwidth=0.5")
<- ggplot(Cars93, aes(x=Price)) +
h2 geom_histogram(binwidth = 1.0) + # 구간의 폭을 1.0으로 설정합니다.
ggtitle("Binwidth=1.0")
<- ggplot(Cars93, aes(x=Price)) +
h3 geom_histogram(binwidth = 1.5) + # 구간의 폭을 1.5로 설정합니다.
ggtitle("Binwidth=1.5")
<- ggplot(Cars93, aes(x=Price)) +
h4 geom_histogram(binwidth = 1.816) + # 구간의 폭을 1.816으로 설정합니다.
ggtitle("Binwidth=1.816 ; Default, range/30")
<- ggplot(Cars93, aes(x=Price)) +
h5 geom_histogram(binwidth = 5) + # 구간의 폭을 5로 설정합니다.
ggtitle("Binwidth=5")
<- ggplot(Cars93, aes(x=Price)) +
h6 geom_histogram(binwidth = 10) + # 구간의 폭을 10으로 설정합니다.
ggtitle("Binwidth=10")
##-----------------
## multiplot function by knitr and Jekyll (author of Cookbook for R)
## 아래 사용자정의 함수를 그대로 카피해서 사용하면 됩니다.
# install.packages("grid")
library(grid)
<- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
multiplot library(grid)
# Make a list from the ... arguments and plotlist
<- c(list(...), plotlist)
plots
= length(plots)
numPlots
# If layout is NULL, then use 'cols' to determine layout
if (is.null(layout)) {
# Make the panel
# ncol: Number of columns of plots
# nrow: Number of rows needed, calculated from # of cols
<- matrix(seq(1, cols * ceiling(numPlots/cols)),
layout ncol = cols, nrow = ceiling(numPlots/cols))
}
if (numPlots==1) {
print(plots[[1]])
else {
} # Set up the page
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
# Make each plot, in the correct location
for (i in 1:numPlots) {
# Get the i,j matrix positions of the regions that contain this subplot
<- as.data.frame(which(layout == i, arr.ind = TRUE))
matchidx
print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
layout.pos.col = matchidx$col))
}
}
}##-----------------
# 하나의 페이지에 여러 개의 플롯을 그리기 : multiplot() 함수 이용
multiplot(h1, h2, h3, h4, h5, h6, cols=2) # 6개의 그래프를 2개의 열로 나타냅니다.
위에서 처럼 한개의 화면에 여러개의 그래프를 배열하기 위해서
multiplot()
함수(by knitr and Jekyll)를 사용하였습니다.binwidth = 5
일 때가 위의 6개 그래프 중에서는 상대적으로 가장 적합해 보이므로 아래 예제부터는binwidth = 5
를 사용하겠습니다.
11.1.5 구간의 수 조정
앞에서는 데이터를 구분할 때 데이터 구간의 폭(binwidth
)으로 조정하였습니다. 이번에는 데이터를 구분하는 전체 구간의 수(bins
)로 조절해 보겠습니다. bins
의 기본 값은 30
입니다.
library(MASS)
# 구간의 수 조정
<- ggplot(Cars93, aes(x=Price)) +
b1 geom_histogram(bins = 10) + # 구간의 수를 10개로 정합니다.
ggtitle("Bins = 10")
<- ggplot(Cars93, aes(x=Price)) +
b2 geom_histogram(bins = 15) + # 구간의 수를 15개로 정합니다.
ggtitle("Bins = 15")
<- ggplot(Cars93, aes(x=Price)) +
b3 geom_histogram(bins = 20) + # 구간의 수를 20개로 정합니다.
ggtitle("Bins = 20")
<- ggplot(Cars93, aes(x=Price)) +
b4 geom_histogram(bins = 25) + # 구간의 수를 25개로 정합니다.
ggtitle("Bins = 25")
# 하나의 페이지에 여러 개의 플롯을 그리기 : multiplot() 함수 이용
multiplot(b1, b2, b3, b4, cols=2) # 6개의 그래프를 2개의 열로 나타냅니다.
자세한 사항은 ? geom_histogram
을 참고하기 바랍니다.
히스토그램의 bin width를 수동으로 설정해주고, bin별로 색깔을 다르게 해서 히스토그램을 그려보겠습니다.
#----------------
# histogram with variable size of bin width and different colors per bins using ggplot2
#----------------
# sample data frame
<- data.frame(var = c(1100, 10000, 100000, 190000, 110000, 220000, 550000, 701000, 790000))
mydf
# numeric notation for large numbers
options(scipen = 30)
library("ggplot2")
# fill color with different colors per bins
$group <- ifelse(mydf $var < 10000, 1,
mydfifelse(mydf $var < 100000, 2,
ifelse(mydf $var < 200000, 3,
ifelse(mydf $var < 500000, 4, 5))))
# breaks of bin
<- c(1000, 10000, 100000, 200000, 500000, 800000)
bins
# draw histogram with variable size of bin width and different colors per bins
ggplot(mydf, aes(x= var)) +
geom_histogram(data=subset(mydf, group==1), breaks = c(1000, 10000), fill="black") +
geom_histogram(data=subset(mydf, group==2), breaks = c(10000, 100000), fill="yellow") +
geom_histogram(data=subset(mydf, group==3), breaks = c(100000, 200000), fill="green") +
geom_histogram(data=subset(mydf, group==4), breaks = c(200000, 500000), fill="blue") +
geom_histogram(data=subset(mydf, group==5), breaks = c(500000, 800000), fill="red") +
scale_x_continuous(breaks = bins, limits = c(1000, 800000)) +
xlab("variable 1") +
ylab("count") +
ggtitle("Histogram with different size of bin width and colors") +
theme(plot.title = element_text(hjust = 0.5, size = 14))
11.1.6 색 지정
위의 히스토그램을 보면 거무튀튀하니 그다지 색깔이 아름답지는 않지요? 그러면 이번에는 색 채우기, 경계선 색 지정하기를 해보겠습니다.
library(MASS)
# 채우기 색, 경계선 색 : geom_histogram(binwidth, fill, colour)
ggplot(Cars93, aes(x=Price)) +
geom_histogram(binwidth=5,
fill = "blue", # 막대의 색을 "blue"로 설정합니다.
colour = "black") + # 막대의 테두리 색을 "black"으로 설정합니다.
ggtitle("히스토그램의 채우기 색과 테두리 색 지정")
자세한 사항은 ? geom_histogram
을 참고하기 바랍니다.
11.1.7 stat_bin()
함수의 이용
geom_*()
함수들은 기본적인 stat_*()
함수를 가지고 있습니다.4 args(geom_histogram)
로 확인해 보면 geom_histogram()
함수는 stat = "bin"
을 알고리즘으로 사용하고 있습니다.
geom_histogram()
함수의 경우에는 stat_bin()
함수가 여기에 해당하며, geom_histogram()
함수 대신에 stat_bin()
함수를 이용할 수 있습니다.
ggplot(Cars93, aes(x=Price)) +
stat_bin(binwidth = 5) # 히스트로그램으로 표현합니다.
자세한 사항은 ? stat_density()
로 확인하기 바랍니다.
11.1.8 데이터 레이블 달기
stat_bin()
함수를 이용하여 데이터 레이블을 표시할 수 있습니다.
library(MASS)
# 채우기 색, 경계선 색 : geom_histogram(binwidth, fill, colour)
ggplot(Cars93, aes(x=Price)) +
geom_histogram(binwidth=5,
fill = "blue", # 막대의 색을 "blue"로 설정합니다.
colour = "black") + # 막대의 테두리 색을 "black"으로 설정합니다.
stat_bin(binwidth = 5,
geom = "text",
aes(label = ..count..),
color = "red",
vjust = -0.5) + # or position = position_stack(vjust = 0.5)) +
ylim(c(0, 25)) +
ggtitle("히스토그램에 데이터 레이블 달기")
11.1.9 그룹별 히스토그램
일변량 연속형 데이터에 대한 그래프를 그룹별로 작성할 수도 있습니다.
예를 들어 지금까지 차량의 가격(Price)으로 히스토그램을 작성하였는데, 이를 요인형 변수인 차량의 유형(Type
) 별로 작성할 수도 있습니다.
이를 위해서는 다음과 같은 3가지 방법으로 가능하며, 각각의 모수에 요인형 변수를 지정해 주는 것입니다.
aes()
함수에colour
,fill
,group
등의 모수를 추가하는 방법입니다.facet_grid()
함수를 이용하는 방법입니다.facet_wrap()
함수를 이용하는 방법입니다.
11.1.9.1 aes()
함수의 모수 이용
aes()
함수에 추가할 수 있는 모수로 colour
, fill
, group
등이 있습니다.
colour = Type
을 추가하면, 각 히스토그램의 막대의 테두리 색이Type
별로 구분이 되어 표시됩니다.fille = Type
을 추가하면 히스토그램의 막대가Type
별로 색이 채워집니다. 이때는geom_histogram()
함수에colour = “white”
와 같이 테두리 색을 지정해 주는 것이 좋습니다.group = Type
을 추가하면 히스토그램이 Type별로 구분이 됩니다. 그러나,geom_histogram()
함수에colour = “white”
와 같이 테두리 색을 지정해 주어야 확인이 가능합니다.
# 그룹별 히스토그램 그리기 : aes()에 모수 지정하기
# colour 모수에 Type 변수를 지정하기
ggplot(Cars93,
aes(x = Price,
colour = Type)) + # 막대를 채우는 색으로 요인형 변수를 지정합니다.
geom_histogram(binwidth=5)
# fill 모수에 Type변수를 지정하기
ggplot(Cars93,
aes(x = Price,
colour = Type,
fill = Type)) + # 막대를 채우는 색으로 요인형 변수를 지정합니다.
geom_histogram(binwidth=5,
colour = "white") # 테두리 선을 지정합니다.
# group 모수에 Type변수를 지정하기
ggplot(Cars93,
aes(x = Price,
group = Type)) + # 막대가 Type별로 구분됩니다.
geom_histogram(binwidth=5,
colour = "white") # 구분된 부분의 테두리 색을 지정합니다.
11.1.9.2 facet_grid()
함수 이용
자동차 유형별(Type
)로 앞의 히스토그램을 비교하기 위해서는 facet_grid(Type ~ .)
또는 facet_grid(vars(Type))
으로 지정하는 방법과 facet_grid( . ~ Type)
으로 지정하는 방법을 각각 살펴 보겠습니다.
library(MASS)
# Type 그룹별 히스토그램 그리기
# 요인(factor) 여부 확인, levels 확인
class(Cars93$Type); levels(Cars93$Type)
## [1] "factor"
## [1] "Compact" "Large" "Midsize" "Small" "Sporty" "Van"
# 요인/집단/그룹(factor)별로 나누어서 히스토그램 그리기
ggplot(Cars93, aes(x=Price)) +
geom_histogram(binwidth=5,
fill = "blue",
colour = "black") +
ggtitle("facet_grid(Type ~ .)") +
facet_grid(Type ~ .) # 히스토그램을 Type 별로 세로로 배열합니다.
위의 히스토그램처럼 자동차의 유형(Type
)인 ‘Compact
,’ ‘Large
,’ ‘Midsize
,’ ‘Small
,’ ‘Sporty
,’ ‘Van
’ 의 6개 유형별로 가격(Price
)의 히스토그램을 그려보면 서로 한눈에 비교가 가능하니 매우 유용하다고 하겠습니다.
참고로, 위처럼 가로로 비교를 하는 것이 아니라 세로로 세워서 그래프를 그린 후에 비교를 하려면 + facet_grid(. ~ Type)
처럼 괄호안의 기입 순서를 바꾸어주면 됩니다.
단, 아래에 예시 그래프를 보면 알겠지만, 차종별로 가격의 분포를 비교하기에는 아래처럼 그래프를 그려서는 안되겠지요? 분석 목적에 맞게 가로로 비교할지, 세로로 비교할지 잘 선택해서 사용하시기 바랍니다.
library(MASS)
# 요인/집단/그룹(factor)별로 나누어서 히스토그램 그리기
# 그룹 히스토그램
ggplot(Cars93, aes(x=Price)) +
geom_histogram(binwidth=5, fill = "blue", colour = "black") +
ggtitle(" facet_grid(. ~ Type)") +
facet_grid(. ~ Type) # 히스토그램을 Type 별로 가로로 배열합니다.
자세한 사항은 ? facet_grid
를 참고하기 바랍니다.
11.1.9.3 facet_wrap()
함수 이용
한편, facet_wrap(
) 함수를 이용하여 각 자동차 유형(Type
)별 히스트로그램을 작성할 수도 있습니다. 1 함수 대신에 facet_wrap(~ Type, ncol = 2)
를 추가해 보겠습니다.
library(MASS)
# 요인/집단/그룹(factor)별로 나누어서 히스토그램 그리기
# 그룹 히스토그램
ggplot(Cars93, aes(x=Price)) +
geom_histogram(binwidth=5, fill = "blue", colour = "black") +
ggtitle("facet_wrap() 함수의 사용") +
facet_wrap(~ Type, ncol = 2) # 히스토그램을 Type 별로 2열로 배열합니다.
자세한 사항은 ? facet_wrap
을 참고하기 바랍니다.
11.1.10 Theme의 사용
ggplot2
패키지는 8 가지의 그래프 테마(Complete Themes)를 제공하고 있습니다. 다음의 예는 theme_class()
함수를 사용하여 X축과 Y축의 서식을 지정하는 예를 보여 주고 있습니다. 또한 참고로 Y축의 값에 컴마(,
)를 삽입하는 예도 포함하였습니다.
## Theme의 사용
ggplot(Cars93, aes(x=Price)) +
geom_histogram(binwidth=5, fill = "blue", colour = "white") +
ggtitle("Theme의 사용") +
::theme_classic() + # 그래프 테마 지정
ggplot2::theme(axis.title.x = element_text(size = 10,
ggplot2face = "italic",
color = "gray",
angle = 0,
vjust = 0.5),
axis.title.y = element_text(size = 10,
face = "bold.italic",
color = "gray",
angle = 0,
vjust = 0.5)) + # X축과 Y축의 서식 스타일 지정
::scale_y_continuous(labels = scales::comma) # Y 값의 천단위에 콤마 표시 ggplot2
자세한 Theme의 사용 방법은 ? theme
을 참고하기 바랍니다.
연습문제
1. Cars93 데이터 세트에 있는 연속형 변수를 히스토그램으로 시각화 하려 합니다.
1-1. MPG.highway
변수에 대한 기본 히스토그램을 작성하시오.
ggplot(Cars93, aes(x = MPG.highway)) +
geom_histogram() +
ggtitle("기본 히스토그램 : MPG.highway")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
##### 1-2. MPG.highway
변수의 구간 폭(binwidth)을 2 로 하여 히스토그램을 작성하시오. {-}
ggplot(Cars93, aes(x = MPG.highway)) +
geom_histogram(binwidth = 2) +
ggtitle("MPG.highway 히스토드램 : binwidth = 2")
1-3. MPG.highway
변수의 구간 수(bins)를 15 로 하여 히스토그램을 작성하시오.
ggplot(Cars93, aes(x = MPG.highway)) +
geom_histogram(bins = 15) +
ggtitle("MPG.highway 히스토드램 : bins = 15")
1-4. MPG.highway
변수에 대한 기본 히스토그램에서 막대의 채우기 색을 “blue”로 테두리 색은 “yellow”로 지정하시오.
ggplot(Cars93, aes(x = MPG.highway)) +
geom_histogram(fill = "blue",
colour = "yellow") +
ggtitle("MPG.highway 히스토그램 : 색 지정하기")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
2. MPG.highway
변수에 대하여 자동차 유형(Type
) 변수를 그룹으로 하여 그룹별 히스토그램을 작성하시오.
단,
aes()
함수를 이용하고, 이 함수에fill = Type
을 모수로 입력하시오.- 구간의 수(
bins =
)는 10개로 조정한다. geom_histogram()
함수에colour = "white"
를 모수로 입력하시오.
ggplot(Cars93,
aes(x = MPG.highway,
fill = Type,
colour = Type)) +
geom_histogram(bins = 10,
colour = "white") +
ggtitle("자동차 유형별 MPG.highway 히스토그램 : aes() 함수 이용")
stat_*() 함수에 대한 설명을 참고하기 바랍니다.↩︎