교육심송용 | 한림대학교 데이터과학스쿨 교수
교육
R에 도전하자···
따라가다보면, 나도 R유저
‘R에 도전하자 ①’부터 ⑤에서 R의 설치부터 시작하여 몇 가지 기능을 따라 해보고 R에서의 색깔처리, R의 기초적인 통계함수 및 R의 벡터 및 데이터 프레임을 사용한 자료처리, 함수작성 등에 대해 알아보았다. 이번 호에서 R 그래픽 장치 및 여러 개의 그래프를 다루는 방법에 대해서 알아보기로 하자.
R 의 그래픽 장치(graphics device)
이전 호의 R에 도전하자에서 plot, pie 명령들을 사용한 보기가 있는데 이 경우 별도의 그래픽 장치를 선택하지 않고 그래픽을 구현하였다. 예를 들어
처럼 barplot 명령을 하면 바로 그래픽 창이 열리면서 그래픽이 만들어진다. 이 경우 다른 그래픽 명령을 사용하면 위의 막대그래프가 사라지고 그 창에 새 그래픽이 만들어진다. 예를 들어 같은 자료로 원그래프를 그리면
로 앞의 막대그래프 자리에 원그래프가 그려져 두 그래프를 비교하려고 한 경우 두 그래프가 동시에 그려지지 않아 어려움에 봉착한다.
R은 여러 가지 그래픽 장치를 제공하는데 그래픽을 사용할 때 기본값으로 그래픽 창이 열리는 것으로 지정되어 있어서 위의 예처럼 그래픽 창이 없으면 새로 열고, 기존 창이 있으면 기존 창에 그리게 된다(덮어 씀). R이 제공하는 그래픽 장치는 크게 세 가지러 분류할 수 있다.
1. win.graph 는 R에서 바로 창을 띄워 그래픽을 구현하게 되고,
2. bmp, jpeg, png, tiff는 각각 BMP 형식, JPG 형식, PNG 형식 및 TIFF 형식의 파일로 그래픽을 저장하게 된다.
3. PDF, PostScript 형식이 있는데 이 두 형식은 앞의 형식과 달리 생성된 그래픽이 여러 페이지에 저장될 수 있다. 즉, win.graph, bmp, jpeg, png, tiff는 한 장치에 한 개의 그래픽만 들어가나 pdf나 postscript 장치는 두 개 이상의 그래픽을 만들면 각각의 그래픽이 한 페이지가 되어 여러 개의 그래픽을 여러 페이지에 저장할 수 있다.
win.graph 함수와 윈도우 그래픽 장치
win.graph 함수는 그래픽 장치로 R에서 새 그래픽 창을 생성하는 함수이다. 이 함수는
win.graph(width, height, pointsize)
로 사용하며 width와 height는 열릴 그래픽 창의 크기를 인치 단위로 설정하고 기본값은 둘 다 7이다. win.graph의 결과가 대화형 창이 열리는 것이라서 마우스 드래그를 통해 창의 크기를 조정할 수 있으므로 width와 height는 대개 별도로 설정하지 않는다. pointsize는 글자 크기인데 기본값은 12(포인트)이다. 예를 들어 위의 원그래프를 그리기 위해
와 같이 win.graph에 pointsize에 20을 설정하면 글자 1, 2, 3, 4의 크기가 20 포인트로 커졌음을 앞선 원그래프와 비교해 보면 알 수 있다. 두 개 이상의 창을 열려면 win.graph 명령을 두 번 이상 하면 된다. 즉,
> win.graph()
> barplot(x)
> win.graph()
> hist(rnorm(100), col=rainbow(10))
명령의 결과는 처음의 win.graph에 의해서 창이 열리고, 이 창에 barplot을 그리고, 두 번째 win.graph 명령에 의해 새 그래픽 창이 하나 더 열리게 되며 이 창에 hist 명령에 의해 정규분포의 난수 100개에 대한 히스토그램을 그리게 된다. 결과는 다음과 같이 두 개의 그래픽 창이 열리고 두 창에 각각의 그래픽이 생성되었다.
와 같이 win.graph에 pointsize에 20을 설정하면 글자 1, 2, 3, 4의 크기가 20 포인트로 커졌음을 앞선 원그래프와 비교해 보면 알 수 있다. 두 개 이상의 창을 열려면 win.graph 명령을 두 번 이상 하면 된다. 즉,
그래픽 장치 닫기 – dev.off와 graphics.off
생성된 그래픽 장치를 닫는 것은 dev.off나 graphics.off 함수로 실행한다. 이 함수에 매개변수를 사용하지 않으면 가장 최근 그래픽 장치를 닫으며, 매개변수로 그래픽 장치 번호를 주면 해당 번호의 그래픽 장치를 닫는다. 위의 그림에서 그래픽 창의 타이틀 바(title bar)를 보면 그래픽 장치의 번호가 2와 3이 사용되었음을 알 수 있는데, 이 상태에서
> dev.off( )
또는
> dev.off(3)
를 명령하면 3번 장치의 히스토그램 창이 닫히고,
> def.off(2)
를 하면 2번 장치의 막대그래프 창이 닫힌다. win.graph의 경우 대화형 창이 생성되는 장치이므로 마우스로 해당 창을 닫는 것이 더 편리할 수 있어서 dev.off 함수로 개별 창을 닫지 않아도 되나 뒤에서 소개할 다른 장치들은 이 함수를 사용하는 것이 좋다.
열려진 모든 그래픽 장치를 한 번에 닫는 명령으로 graphics.off 함수를 사용할 수도 있다. 위의 창에서
> graphics.off( )
를 명령하면 두 창이 한꺼번에 닫힌다. dev.off와 graphics.off 함수는 뒤에서 소개할 장치에도 같은 방법으로 적용된다.
그래픽 장치 닫기 – dev.off와 graphics.off
bmp, jpeg, png, tiff 함수는 이름 그대로 R 그래픽을 BMP 형식, JPG 형식, PNG 형식, TIFF 형식으로 저장한다. 이 그래픽 장치가 열린 상태에서 그래픽 명령을 실행하면 결과가 바로 지정된 파일로 저장되어 R 콘솔에는 아무 메시지도 출력되지 않으며(메세지가 출력되면 에러 메시지 등 뭔가 잘못되었을 가능성이 크다) 당연히 그래픽 창도 열리지 않는다. 요즘처럼 컴퓨터의 속도가 빨라진 경우 마치 R이 아무 것도 하지 않은 것처럼 보이기도 한다. 이들 함수는 각각
bmp(filename = "Rplot%03d.bmp", width = 480, height = 480, units = "px",
pointsize = 12, bg = "white", ...)
jpeg(filename = "Rplot%03d.jpg", width = 480, height = 480, units = "px",
pointsize = 12, quality = 75, bg = "white", ...)
png(filename = "Rplot%03d.png", width = 480, height = 480, units = "px",
pointsize = 12, bg = "white", ...)
tiff(filename = "Rplot%03d.tif", width = 480, height = 480, units = "px",
pointsize = 12, compression = c("none", "rle", "lzw", "jpeg", "zip", "lzw+p",
"zip+p"), bg = "white", ...)
으로 사용법이 거의 같으며 저장 형식에 따라 한두 개의 매개변수가 더 있는 경우가 있다. 각 매개변수는 다음과 같이 설정한다.
•filename은 그래픽을 저장할 파일의 이름을 설정하며, 파일 이름만 준 경우 R의 현재 작업디렉토리에 파일을 만들게 되므로 특정한 경로에 가져다 두고 싶으면 파일의 전체 경로을 주거나 setwd 명령으로 R의 기본 작업 디렉토리를 변경하여야 한다. filename은 생략하면 Rplot001, Rplot002 등으로 R이 자동으로 번호를 붙여 기본 작업 디렉토리에 파일을 생성하며 파일확장자는 저장형식에 따라 bmp, jpg, png, tif로 자동생성된다.
- 파일의 경로구분: 윈도우의 경우 경로구분은 \(자판에서 ₩)를 사용하나 R에서 \는 특수문자이므로 경로구분에는 / 또는 \\(두 개 붙여 씀)를 사용한다. 예를 들어 파일의 전체 경로가 C:\mydata\myfolder\pic.jpg 이면 이면 R에서는 C:\\mydata\\myfolder\\pic.jpg 또 는 C:/mydata/myfolder/pic.jpg를 사용한다.
- R에서 현재 작업 디렉토리는 getwd()를 사용하여 확인할 수 있고, 작업디렉토리를 바꾸려면 setwd 함수를 사용할 수 있다. setwd 함수를 사용하면 이후 생성되는 파일은 특별히 경로를 지정하지 않으면 setwd에서 지정한 경로를 사용한다.
> getwd()
[1] "C:/Users/Sim/Documents"
는 현재의 작업 디렉토리이며 이를 D:\HWP로 바꾸려면
> setwd("D:/HWP/")
를 사용하며 결과로
> getwd()
[1] "D:/HWP"
작업 디렉토리가 변경되었음을 알 수 있다.
- bmp, jpeg, png, tiff로 그래픽 장치를 열고 둘 이상의 그림을 그리면 Rplot001, Rplot002와 같이 번호를 하나씩 증가시켜 그림을 만든다. 여기서 주의해야 할 점은 dev.off나 graphics.off로 그래픽 장치가 닫히면 이 번호도 초기화 된다.
- 위의 그래픽 장치로 파일이 만들어질 때 기존에 같은 이름의 파일이 존재하더라도 사용자 확인없이 덮어쓰므로 파일이름을 줄 때는 기존에 같은 이름의 파일을 지워도 되는지 확인하여야 한다. 파일이름을 주지 않더라도 Rplot001 등이 말없이 덮어써짐에 함께 유의하여야 한다.
•width, height는 만들어질 파일의 폭과, 높이를 설정하며
•units는 단위를 설정한다. 기본값은 픽셀이다.
•pointsize와 bg: 각각 글자크기 및 배경색을 설정한다.
•quality: jpeg 함수에는 quality를 추가 설정할 수 있는데 JPEG이 압축파일이라 압축의 정도를 얼마나 할 것인지 설정하는 것으로 quality가 높을수록 압축이 덜되어 파일크기는 커지고 그림의 정밀도는 낮아진다.
•compression: tiff 함수의 compression은 tiff 파일을 압축할 것인지, 압축한다면 어떤 방법으로 할 것인지 설정하며, 기본값은 압축하지 않는 것이다. 따라서 tiff 파일은 일반적으로 파일크기가 크다.
위의 함수를 이용하여 그래픽을 저장하는 예를 살펴보자. 이를 위해 먼저 파일을 저장을 폴더를 지정하자.
> setwd("D:/HWP/lecture/기고문/통계진흥원/images")
이제 jpeg 장치를 열어 100개의 난수를 표준정규분포에서 만들어 이를 hist.jpg에 저장하려면 아래와 같이
> jpeg("hist.jpg")
> hist(rnorm(100), col=rainbow(10))
명령해보자. 파일 탐색기를 통해 이 파일이 생성되었음을 확인할 수 있으나 이 파일은 R 그래픽에 의해 열려있는 상태라 다른 프로그램은 아직 이 파일을 열지 못한다. 따라서
> dev.off( )
로 장치를 닫아주면 결과가 저장되고 다른 그래픽 앱(GIMP, irfanview, 포토샵 등)으로 이 파일을 열거나 편집 등을 할 수 있다. 이번엔 파일 이름 없이 PNG 장치를 열어보자. 이를 위해
> png( )
로 장치를 열고 두 개의 그래픽 명령을 사용하면
> hist(rnorm(100), col=rainbow(10), freq=F)
> curve(dnorm, from=-3, to=3)
파일 탐색기에서 이 파일이 생성된 것을 확인할 수 있으며, 더 이상 다른 그림을 그리지 않으며 다음 명령으로 장치를 닫으면 된다.
> dev.off( )
이 경우 PNG 장치를 파일 이름 없이 열었으므로 파일명은 Rplot001.png 등이 되며, 두 개의 그래픽 명령이 실행되었으므로 정확하게는 Rplot001.png와 Rplot002.png가 생성되었음을 알 수 있다. 위 명령 결과 파일탐색기를 확인해보면 다음과 같이 파일들이 생성되어 있음을 알 수 있다(파일 탐색기가 ‘아주 큰 아이콘으로 보기’로 설정된 결과임)
위에서 만든 세 개의 파일은 일반적인 jpg, png 파일이므로 GIMP나 포토샵 등 이미지 편집 프로그램을 사용해 편집이 가능하다. bmp나, tiff 도 저장형식의 차이를 제외하면 사용법 및 결과물을 얻는 방법은 거의 같으므로 위의 함수 jpeg이나 png와 같은 방법으로 시도해 보기 바란다.
pdf와 postscript 함수
PostScript는 한 동안 출판에서 표준으로 사용하던 형식 중의 하나로 텍스트 파일로 저장되며 PostScript language로 작성된다. 텍스트 파일이라 파일의 크기가 큰 것이 단점 중의 하나이다. 요즘은 PDF가 표준으로 많이 사용된다. 그래픽을 PDF와 PostScript 형식으로 저장하려면 각각 pdf 및 postscript 함수를 사용하며 이 두 명령은
pdf(file = if(onefile) "Rplots.pdf" else "Rplot%03d.pdf", width, height,
onefile, paper, bg, fg, ... )
및
postscript(file = if(onefile) "Rplots.ps" else "Rplot%03d.ps", onefile, width, height,
bg, fg, horizontal, paper, ...)
로 사용한다. 매개변수는
•file: 앞에서 마찬가지로 그래픽을 저장할 파일 이름을 설정한다. 아래의 onefile이 FALSE이면 앞의 bmp, jpeg 등의 장치와 마찬가지로 각 그래픽 명령이 있을 때마다 Rplot001, Rplot002 등으로 이름을 붙이며 각각의 파일에 한 개의 그래픽이 만들어진다. 이 값이 TRUE이면 그래픽 장치가 닫힐 때까지 한 파일에 모든 그래픽을 그리며 각 그래픽은 이 파일의 한 페이지씩 구성된다.
•onefile: 장치가 열린 후 둘 이상의 그래픽이 있을 때 이를 하나의 파일로 할지 각각의 파일로 할지 설정하며 기본값은 TRUE로 한 파일에 저장한다.
•bg, fg: 배경색과 전경색을 설정한다. 배경색은 "transparent"가 기본값, 전경색은 "black"이 기본값이다.
•width, height: 그림의 크기를 설정한다. 단위는 인치이다.
•horizontal: 그림을 가로로 할지 세로로 할지 설정한다. 기본값은 가로방향이다.
•paper: 종이 크기 설정이다. 가능한 값은 "a4"(A4), "letter"(미국 letter size), "legal", "executive" 또는 "a4r"(A4 가로방향) 등이다. 기본값은 "special"로 width, height 값에 주어진 크기로 만든다. "default"로 설정하면 option에 설정된 papersize 값을 사용한다. option에 사용된 papersize는 options()$papersize로 확인할 수 있으며 운영체계에 따라 한글 윈도우의 경우 이 값은 대개 "a4"이다.
이제 pdf 함수를 사용하여 그래프를 pdf 파일에 저장하기 위해 세 개의 그래픽-히스토그램, 원그래프, 막대그래프를 다음의 명령으로 생성하는 예를 생각해 보자.
> freq <- c(10,20,30,40)
> names(freq) <- LETTERS[1:4]
> pdf(file="E:/HWP/lecture/기고문/통계진흥원/images/graphs.pdf", paper="a4")
> hist(rnorm(100), col=2:8)
> pie(freq, col=2:6)
> barplot(freq, col=2:6)
> dev.off()
위 명령의 결과로 graphs.pdf 파일이 경로 E:\HWP\lecture\기고문\통계진흥원\images에 생성되었으며, 이 파일엔 위의 hist, pie, barplot 함수의 결과가 한 페이지씩 구성하여 세 페이지짜리 PDF 파일이 생성된다. 이 파일을 Adobe PDF Reader로 열어보면 다음과 같다.
참고 R에서 대화형으로 그래프를 생성한 후(즉, win.graph 장치에 그래프를 만든 후) 그래픽 창을 활성화하고 File → Save as를 선택하면 다음의 그림에서 보는 것처럼 윈도우에 보이는 그래프를 metafile(클립보드), PostScript, PDF, png, jpg, bmp, TIFF 등으로 저장할 수 있다.
또한 그림영역에서 마우스 오른쪽 버튼을 클릭하여도 클립보드로 복사하거나 일부 형식으로 그림을 저장할 수 있다. 그렇다면 위의 함수들은 굳이 사용할 필요가 있을까 의문을 가질 수 있다. 하지만 대화형으로 하나씩 분석하는 경우에는 문제가 없으나 함수 작성 등을 통해 한 자료에 대해서 한꺼번에 여러 명령을 수행하는 경우 그래픽을 별도로 저장하여 분석이나 보고서 등에서 사용하는 것이 편하므로 위의 그래픽 장치 함수를 이해하고 구현할 수 있어야 한다.
한 장치에 두 개 이상의 그래프 그리기 - par 함수와 mfrow, mfcol
현재까지 그래픽은 한 화면에 하나씩 그리기만 알아보았는데 R은 한 그래픽 화면을 표의 칸처럼 나눠 각 칸에 그래픽을 하나씩 그리는 방법을 제공한다. 예를 들어 그래픽 영역을 상하 두 개로 나누어 위아래에 각각 다른 그림을 그리거나, 화면을 2개의 행, 2개열을 가진 4개의 영역으로 나누어 4개의 그림을 그리는 것이 가능하다. 이 방법은 그래픽 매개변수를 변경하는 간단한 방법으로 가능하다. 그래픽 변수의 변경은 par 함수를 사용하고, 이 함수의 매개변수 중 mfrow 또는 mfcol 값을 바꾸어 줌으로 가능하다. mfrow, mfcol은 그래픽 영역이 분할할 때 사용할 행의 개수와 열의 개수 두 값을 인수로 갖는다. 기본값은 c(1,1)이며 설정하는 방법은 c(nrow, ncol) 형식으로 설정한다. 기본값이 c(1,1)이므로 행도 1개 열도 1개이기 때문에 그래픽 영역에 그림을 하나만 그리게 된다.
c(nrow, ncol)에서 nrow와 ncol은 그래픽 영역을 칸으로 나눌 때 각각 행의 개수와 열의 개수를 의미한다. mfcol은 그림의 순서가 열우선이며, mfrow는 그림순서를 행우선으로 한다. 다음은 각각의 mfcol 또는 mfrow의 설정에서 그림 영역이 나누어진 형태와 그림의 순서를 그림으로 표시한 것이다.
par 함수로 그래픽 설정을 변경한 경우, 다시 변경할 때까지 변경된 설정이 계속 유지되므로 par 함수로 설정을 변경할 때는 그림을 그린 후 그래픽 설정을 이전의 값으로 되돌려 두는 것이 권장된다. 이를 위해서는 대개 원래의 값을 임시로 저장했다가 그래픽 명령을 실행한 후 임시로 저장했던 값을 다시 par 함수를 사용하여 설정하는 방법을 사용한다. 예를 들어 mfrow를 변경한 경우
omfrow <- par("mfrow")
그래픽 명령들
로 현재의 mfrow 값을 omfrow(old mfrow라는 의미)에 저장한 후 그래픽 명령들을 실행한 뒤 다시 par 함수로 mfrow의 값을 원래 값으로 되돌린다. 함수 내에서 이 방법을 사용할 때는 대개 on.exit 함수를 사용하여 함수가 끝날 때 자동으로 동작되도록 한다.
이제 한 그래픽 영역에 둘 이상의 그림을 넣은 예를 생각해보자. 다음 명령
> omfrow <- par("mfrow")
> par(mfrow=c(1,2))
> hist(rnorm(100), col=rainbow(8))
> curve(dnorm, from=-3, to=3)
> par("mfrow"=omfrow)
의 결과는 아래의 그림과 같이 한 그림영역에 두 개의 그림을 가로로 그리게 된다. 위 명령의 첫 줄과 마지막 줄은 각각 현재의 그래픽 변숫값을 저장하고 그림 그리기가 끝난 후 원래의 설정으로 바꾸어 주는 과정이며 mfrow가 c(1,2)로 설정되었으므로 하나의 행, 두 개의 열로 한 화면이 구성되어 그림영역이 좌우로 반반씩 나누어짐을 알 수 있다.
이번엔 그래픽 영역을 로 나누되 한 번은 mfrow를, 한번은 mfcol을 설정해보자. 이렇게 4개의 그래픽 영역을 만들고 평균인 10, 20, 30이고 분산은 모두 1인 난수를 1,000개씩 생성해서 히스토그램을 그려보자. 그래픽 영역은 4개이나 일부분에만 그릴 수 있음을 확인하기 위해 그림은 3개만 그려 보도록 한다. 먼저 mfrow를 사용하여
> omfrow <- par("mfrow"); omfcol = par("mfcol")
> par(mfrow=c(2,2))
> for (i in 1:3) hist(rnorm(1000, i*10, 1), col=rainbow(8))
세 개의 히스토그램을 그린 후
> win.graph()
로 새 그래픽 창을 생성한 다음
> par(mfcol=c(2,2))
> for (i in 1:3) hist(rnorm(1000, i*10, 1), col=rainbow(8))
> par("mfrow"=omfrow, "mfcol" = omfcol)
명령한다. 위 명령의 결과는 아래의 그림이며 왼쪽 그림은 mfrow를 설정하여 그림의 순서가 행 우선으로 채웠고, 오른쪽 그림은 열 우선으로 채웠음을 x 축의 값을 참조하여 평균값이 10, 20, 30이 되는 그림으로 알 수 있다.
위에서 사용한 for는 반복문으로 1:3, 즉, i의 값이 1, 2, 3일 때 hist(rnorm(1000, i*10, 1), col=rainbow(8)) 각각 한 번씩 실행하게 되어 평균이 각각 i*10=10, 20, 30일 때의 정규분포 난수를 생성하여 히스토그램을 그리게 된다.