본문 바로가기

회사생활/R

한눈에 정리하는 ggplot2를 이용한 R 시각화 기초 2

한눈에 정리하는 ggplot2 를 이용한 R 시각화 기초 2




1달 반만에 정리해서 포스팅하는 R 시각화 기초 2탄이다. 1탄에서는 ggplot2를 이용한 기본이 되는 옵션들 전반에 대하여 알아보았다. 2탄에서는 시계열 데이터를 중심으로 하는 시계열 그래프, 선 그래프를 시각화하는 방법에 대하여 포스팅해보려고 한다.




▼ ggplot2 라이브러리를 이용한 기본적인 시각화 코드 ▼

2017/03/17 - [Analysis/R] - 한눈에 정리하는 ggplot2를 이용한 R 시각화 기초 1




특히 시계열 데이터를 다룰 때 x축은 고정하고 여러 변수의 값을 같은 y축에 여러 선으로 표현하는 그래프를 그리는 법과 범례를 다루는 법에 대하여 정리해보았다.


우선 시계열 데이터를 만들기 위해 iris 데이터에 seq 변수를 붙여준다.

data <- cbind(seq = as.integer(rownames(iris)),  iris)


x축은 seq, y축는 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width로 이루어진 선 그래프를 그리기 위해 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width 4가지 y축 변수에 대하여 색상을 만들고 변수명을 붙여주자.

cols <- topo.colors(4, alpha = 0.5)
names(cols) <- names(data)[2:5]



(1) melt 함수를 이용하는 방법


ggplot2로 위와 같은 시각화를 할때에는 일반적으로 많이 사용하는 방법이다. 하지만 데이터의 형태를 바꾸어야 하기 때문에 데이터의 크기가 큰 경우에는 처리 성능에 부담이 될 수 있다.


먼저 reshape2 라이브러리의 melt 함수로 데이터 구조를 Wide 형태에서 Long 형태로 바꾼다.

library(reshape2)
melt_data <- melt(data, id.vars = c("seq", "Species"))


melt_data는 seq, Species, variable, value 변수로 이루어진 데이터입니다. melt_data를 가지고 x축은 seq, y축은 value, 색(colour)은 variable에 따라 구분된 선 그래프를 그리는 코드를 작성해봅시다. (colour는 오타가 아닙니다.)

library(ggplot2)
g <- ggplot(melt_data) + geom_line(aes(x = seq, y = value, colour = variable), cex = 0.8, show.legend = T)
g

# cex = 선 두께
# show.legend = 범례 보이기



지금 코드로도 우리가 원하는 그래프의 형태는 나왔지만 이 코드에서 추가적으로 선의 색상와 범례 라벨링을 바꾸어 보자. 색상은 처음에 만든 cols 색상코드 벡터를 활용한다.

g <- g + scale_color_manual(name='변수명',
                            values = cols[melt_data$variable],
                            labels = c("꽃받침 길이", "꽃받침 너비", "꽃잎 길이", "꽃잎 너비"))
g

# names = 범례 제목
# values = 선 색
# labels = 범례 이름




Melt를 사용하면 코드를 간결하게 짤 수 있지만 데이터 형태가 Long 이어야 하기 때문에 데이터 변환 과정에 부담이 따를 수 있는 단점이 있다.



(2) 반복문을 이용하는 방법


이번에는 아까 만든 Wide 형태의 data 데이터를 melt_data와 같은 Long 형태로 변환하지 않고도 for문을 이용해 동일한 결과를 출력하는 코드를 작성해보자.


반복문을 선을 그릴 변수의 개수만큼 돌려서 선을 그리게 하는 컨셉으로 작성하였다. (미리 알려두자면 아래 코드로는 우리가 원하는 형태의 그래프가 나오지 않는다.)

g <- ggplot(data)
for(i in 2:5){
  # loop_input <- paste0('geom_line(aes(x = seq, data[, ', i, '], colour = names(data)[', i, ']), cex = 0.8, show.legend = T)')
  g <- g + geom_line(aes(x = seq, data[, i], colour = names(data)[i]), alpha = 0.5, cex = 0.2, show.legend = T)
}
g


위와 같은 형태는 우리가 원하던 그래프가 아니라 제일 마지막 변수인 Petal.Width의 선 그래프만 출력된 결과이다. 무엇이 문제인지 찾아보니 ggplot2는 반복문 안에서 정상적으로 작동하지 않는다고 한다. 원인은 잘 모르겠지만 for 뿐만 아니라 while 등에서도 작동하지 않는다.


그래서 반복문 안에 있는 geom_line 함수를 우회해서 사용하는 방법으로 변경해 보았다. (코드 설명은 아래에 달았다.)
g <- ggplot(data)
for(i in 2:5){
  loop_input <- paste0('geom_line(aes(x = seq, data[, ', i, '], colour = names(data)[', i, ']), cex = 0.8, show.legend = T)')
  g <- g + eval(parse(text = loop_input))
}
g
-
-

위 코드를 설명하자면 선을 추가하는 구문인 geom_line을 텍스트 형태로 만들어서 loop_input에 넣고 loop_input을 eval(parse(text = "")) 함수로 다시 코드화하여 실행시키는 방법이다. 위 코드를 실행하면 아래와 같은 결과를 얻을 수 있다.


위 그래프에서 방법 (1) 결과와 동일하게 나오도록 선색, 범례, y축 라벨링을 수정해보자.

g <- g + scale_color_manual(name='변수명',
                            values = cols[names(data)[2:5]],
                            labels = c("꽃받침 길이", "꽃받침 너비", "꽃잎 길이", "꽃잎 너비")) + labs(y = "value")
g


되도록이면 본연의 데이터 형태를 변환하지 않고 사용하는 방법이 성능에 더 좋기 때문에 데이터 형태에 따라서 맞는 형태로 사용하면 될 것 같다.