R에서는 여러 개의 그래프를 합쳐서 하나로 그리기 쉬운데 par() 또는 layout() 함수를 사용한다.
먼저 par()함수를 사용할 때는 인수인 mfrow=c(nrows,ncols)를 사용하여 nrows*ncols개의 plot으로 분할하는데 그림이 그려지는 순서는 열(row)에 의해 채워진다. mfcol=c(nrows,ncols)를 사용해도 비슷한데 이때는 행(column)을 기준으로 채워진다.
예를 들어 다음의 코드는 네개의 plot을 만들고 두열과 두행으로 배열한다. 내장 데이타인 mtcars를 사용한다.
attach(mtcars)
#현재 상태를 opar에 저장한다
opar <- par(no.readonly = TRUE)
# 화면을 2*2로 나눈다
par(mfrow = c(2, 2))
plot(wt, mpg, main = "Scatterplot of wt vs. mpg")
plot(wt, disp, main = "Scatterplot of wt vs disp")
hist(wt, main = "Histogram of wt")
boxplot(wt, main = "Boxplot of wt")
#다시 opar 상태로 되돌린다.
par(opar)
detach(mtcars)
attach(mtcars)
opar <- par(no.readonly = TRUE)
par(mfrow = c(3, 1))
hist(wt)
hist(mpg)
hist(disp)
par(opar)
detach(mtcars)
고수준 함수인 hist()는 디폴트 타이틀이 포함되는데 제목을 나오지 않게 하려면 main= “”을 사용하거나 ann=FALSE를 사용하여 제목과 label 을 나오지 않게 할수 있다.
3.열 또는 행 마다 그림 갯수를 달리할때
layout함수는 layout(mat)와 같은 형식으로 사용하는데 mat는 matrix object로써 여러 plot의 위치를 나타낸다. 다음 코드에서는 하나의 그림이 1열에 배치되고 두개의 그림은 2열에 배치된다.
attach(mtcars)
layout(matrix(c(1, 1, 2, 3), 2, 2, byrow = TRUE))
hist(wt)
hist(mpg)
hist(disp)
detach(mtcars)
4.세밀한 그림 크기의 조절
경우에 따라 각 그림의 크기를 보다 정밀하게 조절하고 싶다면 layout() 함수의 옵션인 width= 와 height= 옵션을 사용할 수 있다. 다음과 같이 사용한다.
상대적인 width는 숫자로 표현되며 절대적인 width는(cm) 1cm()함수를 사용하여 표시한다. 다음의 코드에서 한개의 그림은 1열에 두개의 그림은 2열에 배치되지만 1열의 그림의 높이는 2열 높이의 1/3이며 아래열우측의 그림의 넓이는 아래열좌측 그림 넓이의 1/4이 된다.
attach(mtcars)
layout(matrix(c(1, 1, 2, 3), 2, 2, byrow = TRUE),
widths = c(3, 1), heights = c(1, 2))
hist(wt)
hist(mpg)
hist(disp)
detach(mtcars)
보는 것과 같이 layout()함수를 사용하면 최종 이미지 내의 그래프의 수와 배열, 그리고 상대적인 크기까지 조절할 수 있다. 보다 자세한 내용은 help(layout)을 이용해 보라.
경우에 따라 하나의 의미있는 그래프를 만들기 위해 여러개의 그림을 배열하거나 겹쳐서 그려야 할 경우가 있다. 그러기 위해서는 그림 배치의 미세 조절이 필요한데 fig=라는 그래픽인수를 사용하면 가능하다. 다음의 코드에서는 scatterplot 에 두개의 boxplot를 더해서 전체 그림을 완성했다. 그림 3.18에 그 결과가 있다.
opar <- par(no.readonly = TRUE)
par(fig = c(0, 0.8, 0, 0.8)) # Set up scatter plot
plot(mtcars$wt, mtcars$mpg, xlab = "Miles Per Gallon",
ylab = "Car Weight")
par(fig = c(0, 0.8, 0.55, 1), new = TRUE) # Add box plot above
boxplot(mtcars$wt, horizontal = TRUE, axes = FALSE)
par(fig = c(0.65, 1, 0, 0.8), new = TRUE) # Add box plot to right
boxplot(mtcars$mpg, axes = FALSE)
mtext("Enhanced Scatterplot", side = 3, outer = TRUE,
line = -3)
par(opar)
이 그래프가 어떻게 만들어졌는지 이해하기 위해서는 전체 그래프의 왼쪽-아래코너를 (0,0)으로 생각하고 오른쪽-위를 (1,1)로 생각하자. 아래그림을 보면 이해에 도움이 될 것이다. fig=인수의 형식은 c(x1,x2,y1,y2) 형태의 숫자 벡터이다.
위의코드 중 두번째 줄을 보면 fig=인수는 scatter plot 그래프를 화면 왼쪽 아래를 기준으로 x축위치는 0에서 0.8, y축위치도 0에서 0.8로 지정한다. 위쪽의 boxplot은 가로 위치는 0에서 0.8이고 세로 위치는 0.55에서 1이다. 오른쪽의 boxplot은 x축의 위치는 0.65에서 1이고 y축에서의 위치는 0에서 0.8이다.
이 그림을 그릴때 위쪽의 boxplt을 그릴때 0.8 대신 0.55를 사용한 이유는 boxplot이 scatterplot에 좀더 가깝게 하기 위해서이다. 마찬가지로 오른쪽 boxplot을 그릴떄에도 0.8이 아닌 0.65를 사용했다. 올바른 위치를 얻기 위해서는 여러번 숫자를 바꿔가며 실험해보라
library(DescTools)
## Loading required package: tcltk
# 맥일때만 한글 글꼴지정
# 화면으로 출력할때는 AppleGothic 이용
if(Sys.info()[["sysname"]] == "Darwin") { par(family="AppleGothic") }
tail(d.pizza)
## index date week weekday area count rabate price operator
## 1204 1204 2014-03-31 14 1 Westminster 4 TRUE 46.76 Rhonda
## 1205 1205 2014-03-31 14 1 Westminster 3 FALSE 41.97 Rhonda
## 1206 1206 2014-03-31 14 1 Camden 3 FALSE 42.97 Rhonda
## 1207 1207 2014-03-31 14 1 Brent 2 FALSE 26.98 Rhonda
## 1208 1208 2014-03-31 14 1 Brent 6 TRUE 75.55 Rhonda
## 1209 1209 2014-03-31 14 1 Camden 4 TRUE 69.66 Rhonda
## driver delivery_min temperature wine_ordered wine_delivered
## 1204 Carpenter 26.8 39.6 0 0
## 1205 Farmer 31.2 35.7 0 0
## 1206 Carter 12.3 48.3 0 0
## 1207 Carter 9.1 45.7 0 0
## 1208 Carpenter 11.0 43.8 0 0
## 1209 Farmer 15.0 43.5 1 1
## wrongpizza quality
## 1204 FALSE low
## 1205 FALSE low
## 1206 FALSE medium
## 1207 FALSE medium
## 1208 FALSE medium
## 1209 FALSE medium
# the results (and the plots) will either be displayed in the console
Desc(d.pizza[,c("driver","temperature","count","weekday","wine_ordered")], plotit=TRUE)
##
## -------------------------------------------------------------------------
## 'data.frame': 1209 obs. of 5 variables:
## 1 $ driver : Factor w/ 7 levels "Butcher","Carpenter",..: 7 1 1 7 3 7 7 7 7 3 ...
## 2 $ temperature : num 53 56.4 36.5 NA 50 27 33.9 54.8 48 54.4 ...
## 3 $ count : int 5 2 3 2 5 1 4 NA 3 6 ...
## 4 $ weekday : num 6 6 6 6 6 6 6 6 6 6 ...
## 5 $ wine_ordered: int 0 0 0 0 0 0 1 NA 0 1 ...
##
## -------------------------------------------------------------------------
## 1 - driver (factor)
##
## length n NAs levels unique dupes
## 1'209 1'204 5 7 7 y
##
##
## level freq perc cumfreq cumperc
## 1 Carpenter 272 .226 272 .226
## 2 Carter 234 .194 506 .420
## 3 Taylor 204 .169 710 .590
## 4 Hunter 156 .130 866 .719
## 5 Miller 125 .104 991 .823
## 6 Farmer 117 .097 1108 .920
## 7 Butcher 96 .080 1204 1.000
## -------------------------------------------------------------------------
## 2 - temperature (numeric)
##
## length n NAs unique 0s mean meanSE
## 1'209 1'170 39 375 0 47.937 0.291
##
## .05 .10 .25 median .75 .90 .95
## 26.700 33.290 42.225 50 55.300 58.800 60.500
##
## rng sd vcoef mad IQR skew kurt
## 45.500 9.938 0.207 9.192 13.075 -0.842 0.051
##
## lowest : 19.3, 19.4, 20, 20.2 (2), 20.35
## highest: 63.8, 64.1, 64.6, 64.7, 64.8
##
## Shapiro-Wilks normality test p.value : <2e-16
## -------------------------------------------------------------------------
## 3 - count (integer)
##
## length n NAs unique 0s mean meanSE
## 1'209 1'197 12 8 0 3.444 0.045
##
## .05 .10 .25 median .75 .90 .95
## 1 2 2 3 4 6 6
##
## rng sd vcoef mad IQR skew kurt
## 7 1.556 0.452 1.483 2 0.454 -0.363
##
## Shapiro-Wilks normality test p.value : <2e-16
##
##
## level freq perc cumfreq cumperc
## 1 1 108 .090 108 .090
## 2 2 259 .216 367 .307
## 3 3 300 .251 667 .557
## 4 4 240 .201 907 .758
## 5 5 152 .127 1059 .885
## 6 6 97 .081 1156 .966
## 7 7 34 .028 1190 .994
## 8 8 7 .006 1197 1.000
## -------------------------------------------------------------------------
## 4 - weekday (numeric)
##
## length n NAs unique 0s mean meanSE
## 1'209 1'177 32 7 0 4.441 0.059
##
## .05 .10 .25 median .75 .90 .95
## 1 1 3 5 6 7 7
##
## rng sd vcoef mad IQR skew kurt
## 6 2.019 0.455 2.965 3 -0.345 -1.170
##
## lowest : 1 (144), 2 (117), 3 (134), 4 (147), 5 (171)
## highest: 3 (134), 4 (147), 5 (171), 6 (244), 7 (220)
##
## Shapiro-Wilks normality test p.value : <2e-16
## -------------------------------------------------------------------------
## 5 - wine_ordered (integer - dichotomous)
##
## length n NAs unique
## 1'209 1'197 12 2
##
## freq perc lci.95 uci.95'
## 0 1010 .844 .822 .863
## 1 187 .156 .137 .178
##
## ' 95%-CI Wilson
Bivariate Plot
Desc(temperature~driver,d.pizza,plot=TRUE)
##
## Call:
## Desc.formula(temperature ~ driver, d.pizza, plot = TRUE)
##
## -------------------------------------------------------------------------
## temperature ~ driver
##
## Summary:
## n pairs: 1'209, valid: 1'166 (96%), missings: 43 (4%), groups: 7
##
##
## Butcher Carpenter Carter Farmer Hunter Miller
## mean 49.62 43.49' 50.42 50.94 52.14" 47.52
## median 51.40 44.80' 51.75 54.10 55.10" 49.60
## sd 8.787 9.407 8.467 9.024 8.885 8.935
## IQR 11.97 12.50 11.32 11.20 11.58 8.80
## n 96 253 226 117 156 121
## np 0.082 0.217 0.194 0.100 0.134 0.104
## NAs 0 19 8 0 0 4
## 0s 0 0 0 0 0 0
##
## Taylor
## mean 45.09
## median 48.50
## sd 11.442
## IQR 18.40
## n 197
## np 0.169
## NAs 7
## 0s 0
##
## ' min, " max
##
## Kruskal-Wallis rank sum test:
## Kruskal-Wallis chi-squared = 141.9, df = 6, p-value < 2.2e-16
## Warning:
## Grouping variable contains 5 NAs (0.414%).
PlotDescNumFact(temperature~driver,data=d.pizza)
Desc(temperature~delivery_min,d.pizza,plot=TRUE)
##
## Call:
## Desc.formula(temperature ~ delivery_min, d.pizza, plot = TRUE)
##
## -------------------------------------------------------------------------
## temperature ~ delivery_min
##
## Summary:
## n pairs: 1'209, valid: 1'170 (97%), missings: 39 (3%)
##
##
## Pearson corr. : -0.575
## Spearman corr.: -0.573
## Kendall corr. : -0.422
PlotDescNumNum(temperature~delivery_min,delivery_min~temperature,data=d.pizza)
PlotMarDens(y=d.pizza$temperature,x=d.pizza$delivery_min,grp=d.pizza$area,
xlab="delivery_min",ylab="temperature",
col=c("brown","orange","lightsteelblue"),panel.first=grid(),
main="temperature~delivery_min|city")
Lattice package는 Trellis그래픽을 R로 구현한 것이다. 이 그래프는 패널이라는 여러개의 독립된 단위 그래프를 가로, 세로 혹은 페이지의 배열로 나타내서 비교분석한다. 다변량 데이타에서 변수들 간의 유기적인 관계나 특징을 파악할 수 있는 유용한 도구라 할수 있다.
barley 데이타는 1930년대에 미국에서 시행된 유명한 보리경작 실험 데이타이다.
library(lattice)
tail(barley)
## yield variety year site
## 115 38.00 Wisconsin No. 38 1932 University Farm
## 116 58.17 Wisconsin No. 38 1932 Waseca
## 117 47.17 Wisconsin No. 38 1932 Morris
## 118 35.90 Wisconsin No. 38 1932 Crookston
## 119 20.67 Wisconsin No. 38 1932 Grand Rapids
## 120 29.33 Wisconsin No. 38 1932 Duluth
aggregate(yield~year+variety,data=barley,mean)
## year variety yield
## 1 1932 Svansota 26.74
## 2 1931 Svansota 34.01
## 3 1932 No. 462 31.70
## 4 1931 No. 462 39.06
## 5 1932 Manchuria 28.73
## 6 1931 Manchuria 34.19
## 7 1932 No. 475 31.71
## 8 1931 No. 475 31.82
## 9 1932 Velvet 31.63
## 10 1931 Velvet 34.49
## 11 1932 Peatland 31.78
## 12 1931 Peatland 36.58
## 13 1932 Glabron 29.36
## 14 1931 Glabron 37.33
## 15 1932 No. 457 31.44
## 16 1931 No. 457 40.25
## 17 1932 Wisconsin No. 38 38.21
## 18 1931 Wisconsin No. 38 40.58
## 19 1932 Trebi 36.33
## 20 1931 Trebi 42.47
barchart(yield~year|variety,data=barley)
dotplot(variety~yield|site,data=barley,groups=year,
key=simpleKey(levels(barley$year),space="right"))
lattice 그래픽을 피자배달 데이타베이스에 적용해보면
histogram(~temperature|driver,col="steelblue",data=d.pizza)
xyplot(temperature~delivery_min|area,d.pizza,col=hred,layout=c(3,1))
붓꽃 데이타를 품종에 따라 그래프를 그려보면 다음과 같다.
plot(Sepal.Length~Petal.Length,data=iris)
plot(Sepal.Length~Petal.Length,data=iris,col=Species)
xyplot(Sepal.Length~Petal.Length|Species,data=iris)
3차원 그래프
data(volcano)
wireframe(volcano,shade=TRUE,aspect=c(61/87,0.4),
light.source=c(10,0,10))
parallel함수
parallel(~iris[,1:4]|Species,iris)
## Warning: 'parallel' is deprecated.
## Use 'parallelplot' instead.
## See help("Deprecated")