제주 탈출 일지

빅데이터 분석 - csv파일을 읽어 barplot 그래프 그리기 본문

빅데이터 분석

빅데이터 분석 - csv파일을 읽어 barplot 그래프 그리기

귀건 2020. 9. 19. 01:55
728x90
반응형

2013년_서울_주요구별_병원현황.csv
0.00MB

이번 시간에 R로 그래프를 그리는 방법에 대해서 학습했는데 이를 잘 정리해둘 필요성이 있다. 

이 포스팅을 실습하게 되면 다음과 같은 두개의 barplot을 얻을 수 있다. 

barplot1
bar2

step 별로 정리를 시작하겠다.

 

step 1. 작업 디렉토리를 설정(선택사항) 및 csv파일 불러오기.

setwd("C:\\Rwd")
data1 <- read.csv("2013년_서울_주요구별_병원현황.csv", header = T)
data1

작업 디렉토리 설정을 하면 경로설정에 있어서 편리하게 사용할 수 있다. 본인은 C 드라이브의 Rwd 폴더를 작업디렉토리로 지정하고, 그 폴더 내에 파일을 넣어서 사용하겠다.

read.csv파일을 보면 경로를 지정하지 않고 단순히 "2013년_서울_주요구별_병원현황.csv"로 파일명만 입력해 준 것을 볼 수 있다. 작업디렉토리를 지정했기 때문에 이렇게 사용할 수 있었다.

 

read.csv를 help창에 검색해보면 데이터 input이라고 나오게 된다.

원형은 다음과 같다.

read.csv(file, header=True, sep = ",", quote = "\"", dec = ".", fill = TRUE, comment.char = "", ...)

하지만 read.table에서 파생된 형태인데, read.csv가 table과 다른 것은 header를 읽을 것인지, 그리고 sep이 ,로 이루어졌는지를 제외하면 모두 동일하게 동작하게 된다.

 

https://randstat.tistory.com/entry/readcsv-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-%EA%B5%AC%EA%B8%80-%EC%84%A4%EB%AC%B8%EC%A7%80-%EC%9D%91%EB%8B%B5%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0

 

read.csv() 함수 사용하기 : 구글 설문지 응답가져오기

na.strings에 대한 설명이 빠져서 추가했습니다. 교재의 PT를 만들다보니 블로그에 조금 소홀했습니다. 오늘은 1장 마지막에 있는 "2장을 위한 준비"에서 사용한 read.csv() 함수를 함께 들여다 보겠습�

randstat.tistory.com

한번 읽어보면 잘 이해할 수 있을 것이다.


Step 2. 읽은 데이터를 barplot으로 그리기.

barplot(as.matrix(data1[1:9, 2:11]), main=paste("서울시 주요 구별 과목별 병원현황-2013년" , "\n", 
                                                "출처[국민건강보험공단]"), ylab="병원수", beside=T, 
                                                col=rainbow(8), ylim=c(0,350))
abline(h=seq(0,350,10),lty=3,lwd=0.2)

barplot은 막대그래프를 그려주는 함수이다. 다음은 해당 함수의 원형이다.

barplot(height, width = 1, space = NULL,
        names.arg = NULL, legend.text = NULL, beside = FALSE,
        horiz = FALSE, density = NULL, angle = 45,
        col = NULL, border = par("fg"),
        main = NULL, sub = NULL, xlab = NULL, ylab = NULL,
        xlim = NULL, ylim = NULL, xpd = TRUE, log = "",
        axes = TRUE, axisnames = TRUE,
        cex.axis = par("cex.axis"), cex.names = par("cex.axis"),
        inside = TRUE, plot = TRUE, axis.lty = 0, offset = 0,
        add = FALSE, ann = !add && par("ann"), args.legend = NULL, ...)

엄청나게 많은 인자들이 존재한다.

하나씩 정리해보겠다.

height 각 기둥의 높이에 해당하는 값 (벡터 또는 행렬)
위의 height의 값이 벡터일 경우에는 각 기둥의 높이가 x의 원소들로 결정되며, 행렬일 경우에는 열의 개수만큼의 기둥이 만들어지
 각 기둥의 높이는 행의 값의 누적이다.
width 막대의 폭
space 막대 간 간격
names.arg 막대나 막대 그룹의 이름을 지정
legend.text 범례의 사용할 char 벡터 지정, 범례의 포함 여부
beside 논리값을 설정하여 두 개 이상의 변수가 행렬로 주어졌을 때 각 기둥 위로 누적할 지(FALSE), 기둥에 나란히 하여 만들지 결정
horiz TRUE이면 수평 막대 그래프로 출력(horizen)
density, angle 막대 내부 밀도와 각도
col 막대 색(color)
border 막대 테두리 색
main, sub 주 제목, 부 제목
xlab, ylab x축 이름, y축 이름(lable)
xlim, ylim x축과 y축 범위 (limit)
xpd fig region 밖에서도 막대를 출력하는지에 대한 여부
axes 그래프의 좌표 축 출력 여부
ces.axis 좌표축, y축에 표시되는 수치형 라벨의 문자 크기
cex.name 범주형 축, x축 이름인 라벨 크기

 

그렇다면 그리는데 사용했던 명령어를 다시 보도록  하자.

barplot(as.matrix(data1[1:9, 2:11]), main=paste("서울시 주요 구별 과목별 병원현황-2013년" , "\n", 
                                                "출처[국민건강보험공단]"), ylab="병원수", beside=T, 
                                                col=rainbow(8), ylim=c(0,350))

처음 height의 경우 as.matrix()를 통해 데이터를 읽어오고 있다. data1을 읽을때 read.csv를 사용했는데, 이 명령어는 read.table과 동일하게 데이터프레임 형태로 반환해준다. (저번 포스팅에서 언급했다.) 이 as.matrix함수는 데이터프레임을 행렬로 바꿔주는 함수이다. height 인자는 벡터 혹은 행렬밖에 넣을 수 없기 때문에 이렇게 변환해준다.

현재 data1의 [1:9, 2:11]을 해주는 이유는 표시과목(내과, 외과, 정형외과...)이 문자형이기 때문에 제외하기 위함이다. 행렬에서는 단 한개의 자료형만 담을 수 있는데, 그때문에 제외하였다.

 

main으로 "서울시 주요.."형태의 이름을 paste 함수를 사용하여 넣어주고 있다. paste함수는 인자를 문자로 변환한 뒤에 벡터로 만들어주게 된다. 이 함수를 사용하여 \n 개행 문자를 사용하려고 한 듯 싶다. 실제로 plot 그림을 살펴보면 다음줄에 출처[..]부분이 표시되어 있다.

 

ylab은 병원수로 y축 이름이 병원수로 출력된다.

 

beside = T의 경우

 

      표시과목 강남구 강동구 강서구 관악구 구로구 도봉구 동대문구 동작구 마포구 서대문구
1         내과     79     60     50     49     31     26       39     38     39       29
2         외과     25      8      6      7      3      8        8      5      9       10
3     정형외과     28     28     26     26     17      8       19     16     19       11
4     성형외과    319      4      1      2      2      0        4      4      9        3
5     산부인과     46     20     14     20     16      8       15     10     22        9
6 소아청소년과     28     28     25     25     23     16       16     20     22       14
7         안과     68     18     15     15     14     10       13     15     14       11
8   이비인후과     51     27     28     22     24     15       22     23     25       18
9       피부과    119     18     15     11     11      6        6     10     15       12

 

이러한 데이터프레임에서 강남구 내과에 대한 값, 강동구 내과에 대한 값, ... 이런 각각의 값들을 모두 bar 형태로 그려준다.

하지만 beside = F의 경우 강남구 내과가 아닌 강남구, 강동구등등..의 병원들이 한꺼번에 누적되어 출력되게 된다. 그림을 보면 확연히 이해될 것이다.

beside = F

col에서는 rainbow(8)의 색, 즉 무지개 색으로 바의 색상을 설정했다. 

 

ylim으로 c(0, 350) 백터를 넣어주었는데, 그림을 보면 y축의 값 구분을 0~350까지 해놓은 것을 확인할 수 있다. 왜 50씩 하였는가에 대해서는 크기에 따라 달라질 것이라고 생각한다.(정확하지 않은 뇌피셜이다..)


Step3. 그래프에 구분선을 그어준다.

abline(h=seq(0,350,10),lty=3,lwd=0.2)

abline은 plot에 선을 그려주는 함수이다. 구분선같은 느낌의 선이다. 함수 원형은 다음과 같다.

abline(a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
       coef = NULL, untf = FALSE, ...)

a와 b는 절편과 기울기라고 한다. 이 인자의 이름이 y = bx + a에서 따온 것이 아닐까 추측한다.

h는 수평선 y의 값들이다. 위 코드의 경우 h = seq(0 , 350, 10)을 사용했는데, 10 단위로 0부터 350까지 수평선을 그어달라는 말이다. 

v는 수직선이다. h와 동일하게 사용하면 된다.

그 이후의 인자는 help를 참고하길 바란다.

 

우리는 lty와 lwd라는 인자를 사용했는데, 이 녀석들은 그래픽 파라미터들이다.

lty는 선모양을 지정해주는데, 3은 점선을 표현해준다.

lwd는 선두께를 지정해주는데, 이 숫자만큼 디폴트 값에 곱해진다.  lwd = 2라고 하면 선이 두배로 굵어지게 된다.

더 자세한 내용은 이 블로그를 참고하길 바란다.^^

https://rfriend.tistory.com/149

 

R 그래프 모수(Graphical Parameters) : 기호 모양 pch, 크기 cex, 선 유형 lty, 선 두께 lwd

지난번 포스팅에서 R 그래프 모수 (Graphical Parameters)를 설정하는 2가지 방법(par(), arguments)에 대해서 소개하였습니다. 이번 포스팅에서는 그래프 모수의 기호, 선 모수 설정에 대해서 하나씩 예를

rfriend.tistory.com


Step4. 범례를 표시한다.

 

name <- data1$표시과목
name
legend(75, 350, name, cex=0.8, fill=rainbow(8), bg="white")

 

이전 as.matrix()하여 제외된 값들이 바로 범례의 표시해야 하는 값들이다. (내과, 외과, 정형외과 ....)

data1에서 $변수명을 통해서 해당 값들만 가져올 수 있다. name을 쳐서 값을 확인해보면 정확히 그 값들만 추출된 것을 확인할 수 있다. (내부의 값을 자주 확인해보길 바란다.)

 

legend가 범례라고 인자에 대해 확인할 떄 살펴보았을 것이다. 인자로도 넣을 수 있지만 함수로 넣는 것도 괜찮은 방법인 것 같다.(물론 오류는 장담못한다..) 이 함수를 사용하면 plot에 범례를 붙여 넣을 수 있다.

legend(x, y = NULL, legend, fill = NULL, col = par("col"),
       border = "black", lty, lwd, pch,
       angle = 45, density = NULL, bty = "o", bg = par("bg"),
       box.lwd = par("lwd"), box.lty = par("lty"), box.col = par("fg"),
       pt.bg = NA, cex = 1, pt.cex = cex, pt.lwd = lwd,
       xjust = 0, yjust = 1, x.intersp = 1, y.intersp = 1,
       adj = c(0, 0.5), text.width = NULL, text.col = par("col"),
       text.font = NULL, merge = do.lines && has.pch, trace = FALSE,
       plot = TRUE, ncol = 1, horiz = FALSE, title = NULL,
       inset = 0, xpd, title.col = text.col, title.adj = 0.5,
       seg.len = 2)

원형이 마치 barplot과 맞먹을만큼 복잡하지만 이 인자들을 다 살펴보지는 않고 실제로 코드에서 사용된 인자에 대해서만 살펴보도록 하겠다.

실제로 사용된 인자는 x, y, legend, fill, cex, bg이다.

x, y의 경우 위치 좌표를 설정해주는 것이고, legend는 아까 추출헀던 값들(범례에 사용될 값들)을 넣어주면 된다.

fill도 그래프에서 사용했던 색들을 넣어주면 된다.

cex는 범례에서 문자의 크기를 결정해주는 하나의 배율이라고 생각하면 된다. 값을 조정해보면 값에 따라 범례에서 글자의 크기가 커졌다 작아졌다 하는 것을 확인할 수 있다.

bg는 배경의 색깔을 지정해주는 것이다.

 

필요한 인자들을 적절히 사용하여 원하는 그림을 그리는 것이 중요하다.(물론 귀찮으면 적절히 템플릿을 하나 만들어 두면 된다.)


Step5. plot을 저장한다.

savePlot("hospital.png", type="png")

이름과 이미지 타입을 설정하여 그린 plot을 저장한다.

저장할 때, "can only copy from 'windows' devices" 에러가 난다면 barplot 그리기 전에 windows()를 추가하고 다시 돌려보면 어떤 창이 하나뜨고 barplot그림을 그리면 그 창에 그려지는 확인할 수 있다.


2번 plot의 경우는 소스만 올려놓고 설명은 하지 않겠다. 한 번 직접 돌려보면서 위의 내용을 복습하기 바란다.^.^

 

※ 참고  par의 경우 파라미터를 설정해주는 함수인데, 그 내부인자인 mfrow 파라미터는 다음과 같다.

그래프 배열

의미

par(mfrow=c(r, c))

그래프를 r개의 행, c개의 컬럼으로 배열한다.

name이 10개의 값이 있으므로 10개의 그래프를 그리기 위해 2행 5열로 배열하려고 하는 것이다. 그 이외 나머지 내용은 위의 내용과 흡사하기 때문에 충분히 할 수 있을 것이라고 생각이 든다.

v1 <- data1[1:9,2]*0.1
v2 <- data1[1:9,3]*0.1
v3 <- data1[1:9,4]*0.1
v4 <- data1[1:9,5]*0.1
v5 <- data1[1:9,6]*0.1
v6 <- data1[1:9,7]*0.1
v7 <- data1[1:9,8]*0.1
v8 <- data1[1:9,9]*0.1
v9 <- data1[1:9,10]*0.1
v10 <- data1[1:9,11]*0.1

par(mfrow=c(2,5))
name <- data1$표시과목
name
#강남
gangnam <- barplot(as.matrix(v1),main="강남구 병원현황",
                               beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                               las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)


axis(2,ylim=seq(0,35,10))
abline(h=seq(0,35,5),lty=2)
#강동
gangdong <- barplot(as.matrix(v2),main="강동구 병원현황",
                               beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                               las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)

 axis(2,ylim=seq(0,35,10))
 abline(h=seq(0,35,5),lty=2)
#강서
 gangseo <- barplot(as.matrix(v3),main="강서구 병원현황",
                                  beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.8,
                                  las=2,ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
 
 axis(2,ylim=seq(0,35,10))
 abline(h=seq(0,35,5),lty=2)
 #관악
 gwanak <- barplot(as.matrix(v4),main="관악구 병원현황",
                                 beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                                 las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
  
  axis(2,ylim=seq(0,35,10))
  abline(h=seq(0,35,5),lty=2)
 #구로
 guro<- barplot(as.matrix(v5),main="구로구 병원현황",
                            beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                            las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
   
 axis(2,ylim=seq(0,35,10))
 abline(h=seq(0,35,5),lty=2)
  #도봉
 dobong <- barplot(as.matrix(v6),main="도봉구 병원현황",
                             beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                             las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
  
 axis(2,ylim=seq(0,35,10))
 abline(h=seq(0,35,5),lty=2)
 #동대문
 dongademun <- barplot(as.matrix(v7),main="동대문구 병원현황",
                             beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                             las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
  
  axis(2,ylim=seq(0,35,10))
  abline(h=seq(0,35,5),lty=2)
  
  #동작구
  dongjak <- barplot(as.matrix(v8),main="동작구 병원현황",
                                    beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                                las=2,ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
  
  axis(2,ylim=seq(0,35,10))
  abline(h=seq(0,35,5),lty=2)
 
  #마포구
   mapo <- barplot(as.matrix(v9),main="마포구 병원현황",
                          beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                           las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
   
  axis(2,ylim=seq(0,35,10))
   abline(h=seq(0,35,5),lty=2)
   
  #서대문구
  seodaemun <- barplot(as.matrix(v10),main="서대문구 병원현황",
                                beside=T,axes=F,ylab="병원수(단위:10개)",xlab="", cex.names=0.85,
                                las=2, ylim=c(0,40), col=rainbow(8), border="white",names.arg=name)
   
  axis(2,ylim=seq(0,35,10))
  abline(h=seq(0,35,5),lty=2)
728x90
반응형
Comments