dh_0e

[R Lang] 그래프 함수, 회귀 분석 정리 (+ ggplot2 정리 및 연습용 code) 본문

R

[R Lang] 그래프 함수, 회귀 분석 정리 (+ ggplot2 정리 및 연습용 code)

dh_0e 2025. 12. 11. 01:30

1. 그래프 레이아웃 및 설정 (par)

그래프를 그리기 전, 화면을 나누거나 겹쳐 그리기 설정을 합니다.

  • par(mfrow = c(행, 열))
    • : 화면을 분할합니다. 예) c(3, 3)은 3행 3열(9개) 격자로 나눕니다.
  • par(new = TRUE)
    • : 중첩 허용. 이미 그려진 그래프 위에 덧그릴 수 있게 합니다 (1회성).
  • par(new = FALSE)
    • : 중첩 해제. 새 그래프를 그릴 때 기존 화면을 지웁니다 (기본값).

 

2. 기본 그래프 그리기 (plot, matplot)

  • plot(x, y, ...)
    • type: 그래프 모양
      • type="p": (Points, 기본값)
      • type="l": (Lines)
      • type="b": 점+선 (Both, 점과 선이 떨어져 있음)
      • type="c": 비워둠 ("b"에서 점만 뺀 모양)
      • type="o": 통과 (Overplotted, 선이 점을 뚫고 지나감)
      • type="h": 수직선 (Histogram, x축에서 데이터까지 수직선)
      • type="s": 계단형 (Steps)
      • type="n": 없음 (None, 축만 그리고 내용은 안 그림)
    • pch: 점의 모양 (숫자 0~25).
    • main, xlab, ylab: 제목 및 축 이름.
    • col: 그래프 색상 지정 (1, 2, 3, 4 or black, red, blue, green)
    • xlim: x축의 표시 범위 지정 (예: c(0, 25)).
    • lwd: 선의 굵기
    • lty: 선의 종류(line, solid, dotted, dashed 등)
    • : 산점도, 꺾은선 등 가장 기본적인 그래프 함수.
    • lines나 abline, matplot 같은 그래프 함수에는 대부분 사용 가능
  • matplot(data, ...)
    • : 다중 그래프. 행렬(Matrix) 데이터를 받아 열(column) 별로 여러 개의 선/점을 한 번에 그립니다.

 

3. 막대 및 파이 차트 (barplot, pie)

  • barplot(data, ...)
    • horiz = TRUE: 가로 방향 막대.
    • beside = TRUE: (행렬 데이터일 때) 막대를 옆으로 나란히 배치.
    • beside = FALSE: (행렬 데이터일 때) 막대를 위로 쌓아서 배치 (기본값).
    • names.arg: 막대 밑에 이름표 붙이기 (막대의 개수와 똑같아야 함)
    • 벡터 데이터일 땐 자동으로 옆으로 나란히 배치됨
    • : 막대그래프를 그립니다.
    • 히스토그램(hist())과 차이점
      • 막대그래프는 성별, 지역 등의 이산형이며 그래프 막대가 분리되어 있음
  • pie(data, ...)
    • radius = 0.8: 원의 반지름 크기 (기본값 0.8).
    • labels: 각 조각에 붙일 이름표.
    • : 파이 차트(원형 그래프)를 그립니다.

 

4. 히스토그램 및 통계 분포 (hist, density)

  • hist(data, ...)
    • freq = FALSE: y축을 빈도(count)가 아닌 밀도(density)로 표시 (선 그래프와 겹쳐 그릴 때 필수).
    • : 도수분포표를 이용한 히스토그램(막대)을 그립니다.
    • 막대그래프(barplot())과 차이점
      • 히스토그램은 키, 나이, 금액 등과 같이 연속적인 자료를 나타낼 때 사용하며 그래프 막대가 붙어 있음
  • density(data)
    • : 데이터의 확률 밀도 함수를 계산합니다. (보통 lines(density(x)) 형태로 곡선을 그릴 때 사용).
  • rnorm(n, mean, sd)
    • : 정규분포를 따르는 난수(무작위 수)를 생성합니다. (n개, 평균 mean, 표준편차 sd).

 

5. 그래프 요소 추가 (lines, abline, legend)

  • 이미 그려진 그래프 위에 덧 그리는 함수들입니다.
  • lines(x, y, ...)
    • : 점들을 잇는 꺾은선/곡선을 추가합니다.(유한한 꺾은선)
  • abline(...)
    • h = 값: 수평선 (Horizontal).
    • v = 값: 수직선 (Vertical).
    • a = 절편, b = 기울기: 사선 ($y=a+bx$).
    • : 화면을 가로지르는 직선을 추가(무한한 직선)
  • legend("위치", legend, ...)
    • : 범례를 추가합니다. (위치: "topleft", "topright" 등).
    • 여러 개 추가 가능
    • 문자열을 추가할 수도 있고 문자열 벡터를 추가할 수도 있음

 

6. 데이터 조작 및 유틸리티 (paste, dplyr)

  • c(...) : 벡터 생성.
  • matrix(...) : 행렬 생성 (nrow 행 개수, ncol 열 개수).
  • cbind(...) : 열(Column) 기준으로 벡터를 합쳐 행렬로 만듦.
  • seq(from, to, length or by) : 등차수열 생성 (그래프의 x축 좌표 만들 때 주로 사용).
    • length=n이면 n개로 나누는 등차수열 생성
    • by=n이면 n 단위 등차수열 생성
  • paste(..., sep="") : 문자열 붙이기. (예: "서울" + "37" + "%" $\rightarrow$ "서울 37%").
  • round(x) : 반올림 함수.

 

7. 단일, 다중 회귀분석

  • lm(): 단순 선형 모형으로 적합시키는 함수
    • lm(종속변수 ~ 독립변수, data=데이터셋)
  • cor.test(테이블명$변수명2)
    • 상관관계가 있으면 cor 값이 1(양의 상관관계) or -1(음의 상관관계)로 나타남
    • 0에 가까울수록 두 변수 간의 상관관계가 없음을 의미
  • coef(회귀분석 모델): 회귀 분석 결과에서 계수만 추출
    • coef(model)[1]: y절편 값
    • coef(model)[2]: 독립 변수 값
  • pairs(target): 여러 변수들 간의 산점도를 한 번에 그려 관계를 확인하는 데 유용
  • predict(회귀분석 모델, data): 모델과 data의 값을 통해 예상 값을 도출해냄
  • stepAIC(회귀분석 모델): 단계적 회귀함수로 모델에서 영향력 없는 변수들 제거
  • glm(종속변수 ~ 독립변수, data): 로지스틱 회귀 분석
    • 독립변수에 '.(dot)'을 사용하면 종속변수를 제외한 나머지 변수들은 모두 독립변수라는 뜻

 

8. Dummy 더미 변수 & 군집, 분류

  • 더미 변수란 0과 1을 값으로 가지는 변수를 의미
  • 범주형 데이터를 수치형으로 변환하여 사용케 하는 변수
    • 모델링의 용이성, 해석의 용이성으로 사용
  • 회귀 모델에서 명목형 데이터를 X로 사용하는 방법은 하나의 명목형 데이터를 여러 더미 변수로 변경하여 사용하는 것
  • 회귀식에서 더미 변수의 의미는 0일 때 해당 변수가 적용되지 않음, 1일 때 적용됨을 뜻함
  • R에서는 명목형 데이터를 character로 두지 않고 factor를 만들어서 적용

  • lm() 함수의 독립변수에 factor형이나 character 형을 넣으면 자동으로 더미화 시켜서 분석

 

군집화와 분류

  • 군집화(Clustering): 주어진 대상 데이터들을 유사성이 높은 것끼리 묶어주는 기술로, 이러한 묶음을 군집, 범주, 그룹 등 다양한 용어로 부름
  • 분류(Classification): 그룹의 형태로 알려진 데이터들이 있을 때, 그룹을 모르는 어떤 데이터에 대해 어느 그룹에 속하는지를 예측하는 기술
  • kmeans(data, centers=k, iter.max=m):
    • data에 있는 행마다 각 변수값을 종합하여 군집을 만듦  
    • data: k-means 알고리즘을 수행할 대상 데이터
    • centers: k를 뜻하는 군집의 개수. 중심을 몇 개로 할 것인지 정해야 함 
    • iter.max: k-means는 최대 반복 횟수를 지정해야 함 (Default=10)
      • 반복 계산을 통해 결과를 산출하게 됨
      • 적당히 반복 계산이 되면 멈추는 것이 효율적
  • k-means를 사용하는 데이터는 군집과의 거리를 기반으로 하기 때문에,
    거리에 대해 같은 의미를 지니는 변수만을 바탕으로 군집을 시도함
  • 숫자가 큰 변수가 영향력이 클 수 있음
    • ex) 키와 몸무게로 사람들을 군집화 시도하면 키가 몸무게에 비해 숫자가 클 것이기 때문에 키의 차이가 군집을 결정하는데 더 영향을 주게 됨
  • 이를 조정하는 방법을 표준화(scale)라 함
  • R에서는 scale(data, center=T, scale=T)로 제공
    • data: 표준화 대상이 되는 데이터. 숫자형만 처리 가능
    • center: 중심을 0으로 조절할 것인지 결정
      • 기본 값은 TRUE이고 FALSE를 하면 숫자 벡터의 평균을 중심으로 유지
    • SCALE: 분포를 표준 정규분포로 조절할 것인지를 결정
      • 기본 값은 TRUE이고 FALSE를 하면 숫자 벡터의 분산을 그대로 유지
  • scale 이후에 오히려 total_SS 값(모델 성능 평가)이 나빠질 수 있음
    • 왜 Scale을 했는데 결과가 더 나쁠까?
      1. 단위가 같음: Iris 데이터는 네 가지 변수 모두 cm 단위로 측정되었습니다. 애초에 키(cm)와 몸무게(kg)처럼 물리적 단위가 다르지 않습니다.
      2. 분산 자체가 정보: Iris 데이터는 꽃잎 길이(Petal.Length)의 차이가 매우 커서 이것이 품종을 구분하는 가장 강력한 힌트(Signal)가 됩니다. 반면 꽃받침 너비(Sepal.Width)는 품종 간 차이가 별로 없는 소음(Noise)에 가깝습니다.
      3. Scale의 부작용: scale()을 하면 모든 변수의 영향력을 똑같이(표준편차 1) 만들어 버립니다.
        • 결과: 품종을 잘 구분해 주던 Petal.Length의 강력한 힘은 줄어들고, 별로 도움 안 되는 Sepal.Width의 목소리가 커져버린 셈입니다.
    • 이것은 Iris 데이터셋의 특성 때문입니다.
    • 이런 식으로 단위가 같은 특성끼리 모여있고, 데이터 크기 차이 자체가 중요 정보일 때는 Scale을 안 하는 게 더 나을 수 있음

 

9. ggplot2

  • ggplot( ) 함수를 이용하여 그래프 틀을 만들고, 그 안에 다양한 이미지 객체 레이어를 계속 포개는 방식으로 그래프를 표현

(1)ggplot + (2) geom_XXXX() + (3) 이외 func()

1. ggplot() 함수: 데이터와 그래프의 틀을 나타내는 부분

  • ggplot(data, aes(x, y, fill))
    • data: 그래프를 작성할 데이터셋
    • x: x축으로 사용할 열 이름
    • y: y축으로 사용할 열 이름
    • fill: 전역 규칙으로 모든 도형들이 이 색상 규칙에 따르도록 함
      • ★변수를 넣으면 그 변수를 기준으로 자동으로 데이터를 쪼갬
        • 누적할 대상을 알려줌
        • 범례(Legend) 생성의 기준이 됨
        • 없으면 누적할 대상이 없어서 그냥 단색 그래프가 됨

2. geom_XXXX() 함수 추가: 그래프의 형식을 나타내는 부분

  1. + geom_bar(stat='identity', fill="color1", color="color2", width=1.0)
    • 추가하여 막대그래프를 생성하는 함수
    • aes() 안에 fill을 추가하여 누적 대상을 구분해야 함
      • 안 하면 구분 기준이 없어서 그냥 단색 막대그래프가 하나로 퉁 하고 나옴
    • stat='identity'
      • 데이터를 가공(카운트) 하지 말고, 데이터 수치 그대로 그래프 높이로 사용하라는 뜻
      • ex) "사과: 10, 배: 5"라는 표를 주면 R이 "사과 옆에 10이라고 쓰여있네?" 높이 10을 그림
      • 이걸 치기 귀찮으면 geom_bar 대신 geom_col()을 사용하면 됨
    • stat='count'
      • identity 옵션이 없는 경우 Y축 값은 해당 데이터의 수가 자동 설정 (stat="count"이 디폴트)
      • R이 각 항목이 몇 번 등장하는지 카운트함
      • aes() 안에 x나 y 중에 하나만 있어야 작동함
        • ggplot(data, aes(x=x축 변수, fill=count 할 변수)) + geom_bar(stat='count')
        • y로 할 경우: y축 변수로 작동하면 그래프를 가로 방향으로 출력
      • ex) "사과, 사과, 배, 사과, 포도 ..." 리스트를 주면 R이 "사과가 3개구나!"하고 3만큼 그림
    • fill="color1": 막대를 채울 색상을 지정 (aes() 밖에 있는 fill)
    • color="color2": 막대의 테두리 색상을 지정
    • width: 막대의 두께를 정함
    • position='dodge': 그룹화 막대그래프 작성
      • 쌓지 않고 그래프 옆으로 펼침
      • barplot의 beside=TRUE와 완벽하게 같은 개념
    • position='fill': 비율 중첩 막대그래프
      • y축을 0~1까지 잡고 각 변수의 비율을 나타내서 꽉 채워서 출력
  2. + geom_line()
    • 추가하면 시계열(선) 그래프 작성
    • orientation="y": 그래프 90도 회전 시킴
      • coord_flip()과 차이
        • coord_flip()은 그래프를 다 그린 뒤 그래프 전체를 90도 돌려서 보여줌
        • orientation="y"는 애초에 그래프를 그릴 때 고개를 돌려 그림
        • ggplot(economics, aes(date, unemploy)) + geom_line() + coord_flip()
          ggplot(economics, aes(unemploy, date)) + geom_line(orientation = "y")
                                   (ggplot에서 x, y도 미리 돌려놈)
          • 둘 다 똑같음
    • ggplot(economics_long, aes(x=date, y=value01, colour = variable)) + geom_line()
      • 이런 식으로  fill 대신 color로 각 그래프를 구분 지어  다중 선 그래프를 출력할 수 있음
        • + facet_wrap(~variable)로 variable 별로 그래프를 쪼개서 출력할 수도 있음
          • 이건 다 따로 나눠서 보여줌
          • 뒤에서 다시 설명
        • col == color == colour(영국식)
  3. + geom_area()
    • 추가하면 영역 그래프 작성
    • geom_bar(막대, 파이 그래프)처럼 ggplot에서 aes안에 fill을 넣어 누적 대상을 구분함
    • position='fill': 비율 누적 영역 그래프 작성
      • 비율 누적 영역 그래프 자동으로 생성해 줌
  4. + geom_point()
    • 추가하면 산포도 작성
    • 특이하게 aes를 한 번 더 추가해서 사용
      • ex) ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width) ) +
                 geom_point(aes(color=Species, shape=Species), size=3)
      • 전역으로 물려받은 x, y는 유지하고 color, shape만 새로 추가함
        • 사실 ggplot(aes())안에 넣든 geom_point(aes())에 넣든 상관 없음
          • ggplot(aes())에 추가: 후에 추가되는 모든 함수들의 전역 조건
          • geom_XXX(aes())에 추가: 해당 시각화 자료만 해당 조건
        • 교수님이 그냥 나눠 논 듯
    • size
      • aes() 안에 size=변수: 하나의 변수를 크기로 비교하는 비교 변수를 추가할 수 있음
      • aes() 밖에 size: 점 크기
    • color
      • aes() 안에 col=변수: 하나의 변수를 색상끼리 비교하는 비교 변수를 추가할 수 있음
      • aes() 밖에 col: 색상 지정
  5. + geom_boxplot()
    • 추가하면 박스 플롯 시각화 생성
    • 마찬가지로 aes() 안의 fill이나 color로 누적 대상 구분
      • geom_bar에서 사용했던 position = 'dodge'를 사용하면 합해져 있던 누적 대상들을 옆으로 나열함
  6. + geom_histogram()
    • aes()에 x만 넣어서 y축은 count로 사용함
      • ggplot(iris, aes(x=Sepal.Width, fill=Species, color=Species)) +
          geom_histogram(binwidth = 0.5, position="dodge") +
          theme(legend.position="top")
      • aes()에 fill, color 둘 다 써도 되고, fill만 써도 색상 별로 나눠짐
        • color만 쓰면 테두리만 나눠지고 안에는 모두 동일한 단색으로 채워짐
    • binwidth: 데이터 구간을 설정한 값으로 간격을 나누어 히스토그램 작성
    • position="dodge"
      • 막대그래프나 박스 플롯에서 했던 것처럼 쌓아 논 막대들을 옆으로 나열함

3. + 그 외 함수: 추가적인 옵션을 선택하는 부분

  • + ggtitle(): 제목 생성
  • + xlab(x): x축 레이블 지정
  • + ylab(y): y축 레이블 지정
  • + labs(x, y): 그래프의 x, y축 레이블 지정
  • + coord_flip(): 그래프를 가로 방향으로 출력
    • 그래프 틀과 그래프 전체를 그리고 돌리는 거라 x축과 y축도 같이 돌아감
  • + theme(plot.title = element_test(size, face, color)): 지정된 그래프에 대한 제목의 폰트, 크기, 색 등을 지정
  • + theme(legend.position=""): 범례(레전드) 어디에 표시할지 지정 레전드 포지션 ㅋㅋ
  • + coord_polar(): 추가하여 막대그래프를 파이 차트로 작성
    • + coord_polar(theta="y", start=0): 원통형 파이 차트 작성

 

10. 비교 시각화

모자이크 플롯

  • 다중변수 범주형 데이터에 대해 그룹별 비율을 면적으로 표시하여 정보 전달
  • mosaicplot(~x축 변수 + y축 변수, data, color, main)
    • ~ 다음의 변수가 x축 방향으로 표시
    • + 다음의 변수가 y축 방향으로 표시
    • data: 모자이크 플롯을 작성할 대상 데이터셋
    • color
      • color=TRUE: y축 변수의 그룹별로 음영을 달리하여 표시 
      • color=c(col1, col2): y축 변수의 그룹별로 색상을 달리하여 표시
    • main: 모자이크 플롯의 제목을 지정

버블차트

  • 산점도 위에 버블의 크기로 정보를 표시하는 시각화 방법
  • 산점도가 2개의 변수에 의한 위치 정보를 표시한다면, 버블 차트는 3개의 변수 정보를 하나의 그래프에 표시
  • symbols(x, y, circles, inches, fg, bg, lwd): 버블을 출력하는 함수
    • x, y: 원의 x, y좌표의 열 삽입
    • circles: 원의 반지름의 열 삽입
    • inches: 원의 크기 조절값
    • fg: 원의 테두리 색
    • bg: 원의 바탕색
    • lwd: 원의 테두리선 두께
  • text(x, y, text, cex, col): 텍스트 출력하는 함수
    • x, y: 텍스트가 출력될 x, y 좌표
    • cex: 폰트 크기
    • col: 폰트 컬러

트리맵

  • 사각타일 형태로 구성되어 있으며, 각 타일의 크기와 색깔로 데이터 크기를 나타냄
  • 각각의 타일은 계층 구조가 있기 때문에 데이터에 존재하는 계층 구조도 표현 가능
  • library(treemap) 필요
  • treemap(data, index=c(a, b), vSize, vColor, type, title)
    • intdex=c(a, b): 트리맵상의 계층구조 설정
      • a(ex. 대륙)가 b(ex. 국가)를 포함하는 순서로 입력 (범위가 큰 순서대로)
      • 하나만(a) 넣으면 타일에 a열 값 표기 목적
    • vSize: 타일의 크기를 결정하는 변수(열)
    • vColor: 타일의 컬러를 지정하는 변수(열)
    • type: 타일 컬러링 방법 (대부분 value)

scale_x_log10, scale_y_log10 함수

  • "+그 외 함수"처럼 +scale_x_log10(), +scale_y_log10()으로 사용
    • +scale_x_log10(): x축에 대해 log 함수 씌운 결과 도출
    • + scale_y_log10(): y축에 대해 log 함수 씌운 결과 도출
  • 데이터에 직접 로그를 취하지 않고도 축의 스케일을 바꾸어 동일한 효과를 낼 수 있음
  • 보통 x축이나 y축에 대한 outlier(혼자만 유독 큰 수)가 있고, 나머지 데이터들이 모여서 분포될 경우 사용
  • + face_wrap() 함수
    • + face_wrap(~변수)를 추가하면 해당 변수의 각 행을 기준으로 그래프가 추가
    • par(mfrow())와 비슷하지만 변수의 개수로 화면을 분할하며, 해당 변수의 행(ex. 년도)마다 그래프가 생성

 

그래프 I, II 연습용 R 코드

plot(cars, main="cars", type="b", pch=13)

data <- c(5, 7, 3, 4, 5, 9, 10)
barplot(data)         # 막대 그래프 작성
par(new=T)            # 겹쳐서 출력 허용 1회성
plot(data, type="o")  # 선 그래프 작성

par(new=F)
plot(c(5, 4, 1, 3, 2, 1:4), type="o")

x <- c(29,14,9,26,15,13,28,24,17,4,19,22,2,25,8,6,16,18,21,30)
y <- c(9,3,26,27,10,21,8,4,28,24,5,6,22,29,20,25,12,1,2,15)
par(mfrow=c(3, 3))
plot(x, y, main="Plot p-type", xlab="x-label", ylab="y-label", type="p")
plot(x, y, main="Plot l-type", xlab="x-label", ylab="y-label", type="l")
plot(x, y, main="Plot b-type", xlab="x-label", ylab="y-label", type="b")
plot(x, y, main="Plot c-type", xlab="x-label", ylab="y-label", type="c")
plot(x, y, main="Plot o-type", xlab="x-label", ylab="y-label", type="o")
plot(x, y, main="Plot h-type", xlab="x-label", ylab="y-label", type="h")
plot(x, y, main="Plot s-type", xlab="x-label", ylab="y-label", type="s")
plot(x, y, main="Plot S-type", xlab="x-label", ylab="y-label", type="S")
plot(x, y, main="Plot n-type", xlab="x-label", ylab="y-label", type="n")

par(mfrow=c(2,1))               # 2x1 화면 분할
data <- c(5, 7, 3, 4, 5, 9, 10) 
barplot(data)                   # 세로형 막대 그래프
barplot(data, horiz=TRUE)       # 가로형 막대 그래프

par(mfrow=c(3, 1))
data <- matrix(c(5, 9, 10, 3, 5, 7, 3, 4), nrow=3, ncol=3) # 행렬 자료구조
barplot(data)
barplot(data, beside=T)
barplot(data, beside=T, main="학생수",
        legend=c("1학년", "2학년","2학년","3학년"))

par(mfrow=c(1,1))
# 그래프 데이터 생성
x <- c(182, 190, 213, 205, 231, 250, 242)
# 선그래프 작성
plot(x, type = "o",col = "red", xlab = "년도", ylab = "억원", main = "매출현황")
y <- c(190, 180, 200, 210, 220, 234, 235) # 이중 선그래프 데이터 생성
lines(y, type = "b", col = "blue")        # 선(+점) 추가, 다중 선그래프

# 기존 그래프 만들기
x <- seq(0, 2 * pi, length = 100)
x
y <- sin(x)
plot(x, y, type = "l", col = "blue", lwd = 2, lty = "dotted") # 점선

# 새로운 선 추가
new_x <- seq(0, 2 * pi, length = 100)
new_y <- cos(new_x)
lines(new_x, new_y, col = "red", lwd = 5, lty = 4) # 대시선 추가

# 다중 그래프 데이터 생성
x <- c(182, 190, 213, 205, 231, 250, 242)
y <- c(190, 180, 200, 210, 220, 234, 235)
z <- c(195, 185, 190, 215, 220, 230, 225)
data <- cbind(x, y, z ) # 행렬 구성
matplot(data, type = "b", col=2:4, pch=1) # 다중 선그래프 작성
lnd <- c("2022년 매출", "2023년 매출", "2024년 매출") # 범례
legend("topleft", legend =lnd , col=2:4, pch=1)

plot(cars, xlim=c(0, 25))
abline(a=-5, b=3.5, col="red") # y절편=-5, 기울기=3.5인 직선
abline(h=0, col="blue") # y=0 인 수평선을 그림
abline(v=0, col="green") # x=0 인 수직선을 그림
abline( a=0, b=1, col="purple") # y절편=0, 기울기=1인 직선

# 데이터 생성
x <- c(1, 2, 3, 4, 5)
y <- c(10, 15, 13, 7, 20)
# 그래프 그리기
plot(x, y, type = "b", col = "blue", pch = 19, main = "point_line & abline")
# 그래프에 추가 요소 추가
abline(h = 10, col = "red", lty = 2, lwd = 3) # 가로선 추가
abline(v = 3, col = "green", lty = 3, lwd = 5) # 세로선 추가
legend("topright", legend = "points", col = "blue", pch = 19) # 범례 추가

data <- c(280, 170, 120, 100, 85)  # 매출액(억 원)
pie(data)                          # 파이 차트 작성
lbls <- c("서울", "부산", "경북", "전남", "충청")
pct <- round(data/sum(data)*100)   # 백분율 계산
lbls <- paste(lbls, pct)     
lbls# 라벨(labels)에 백분율(pct) 추가
# paste("서울", 37) → "서울 37" 이런 식으로 문자열을 합침.
lbls <- paste(lbls,"%",sep="")     # 라벨(labels)에 % 추가
pie(data, labels=lbls, radius=0.8) # 레이블 포함 파이 차트 0.8이 디폴트

hist(cars$speed)

x <- rnorm(300, mean=10, sd=2) # 평균이 10, 표준편차가 2인 300개의 난수 샘플을 생성
hist(x)                        # 히스토그램 작성
hist(x, freq=F)                # freq=F: 빈도가 아닌 밀도로 표시
lines(density(x))              # 확률밀도 히스토그램에 선 추가


install.packages("gapminder")
library(gapminder)
library(dplyr)
# 개별 국가를 대륙별로 묶어 관찰
y <- gapminder %>% group_by(year, continent) %>% summarize(c_pop=sum(pop))
# 대륙별로 각자 다른 color(col), shape(pch)
plot(y$year, y$c_pop, col=y$continent, pch=c(1:length(levels(y$continent))))
# topleft에 범례를 표시
legend("topleft", legend=levels(y$continent), 
       pch=c(1:length(levels(y$continent))), col=c(1:length(levels(y$continent))))








## 10. 회귀 및 로지스틱
plot(cars)
lm(dist~speed, data=cars)
abline(lm(dist~speed, data=cars))
cor.test(cars$speed, cars$dist)
co <- coef(lm(dist~speed, cars))
co
summary(lm(cars))

co
W <- co[1]
B <- co[2]
W
B
speed <- cars[,1]
pred <- W+B*speed
pred
compare <- data.frame(pred, cars[,2], pred-cars[,2])
compare
colnames(compare) <- c('예상dist', '실제dist', '오차')
compare

plot(dist~speed, data=cars)

wt <-mtcars$wt                # 중량 자료
mpg <- mtcars$mpg
wt# 연비 자료
plot(wt, mpg, # == mpg~wt      # 2개 변수(x축, y축)
     main="중량-연비 그래프",  # 제목
     xlab="중량",             # x축 레이블
     ylab="연비(MPG)",        # y축 레이블
     col="red", # point의 color
     pch=19)

vars <- c("mpg","disp","drat","wt") # 대상 변수
target <- mtcars[,vars]
target
pairs(target, main="Multi Plots")

iris.2 <- iris[,3:4]              # 데이터 준비
point <- as.numeric(iris$Species) # 점의 모양
color <- c("red","green","blue")  # 점의 컬러
plot(iris.2, main="Iris plot", pch=point, col=color[point])
legend("topleft", legend = levels(iris$Species), pch = 1:3, col = color)
levels(iris$Species)

library(mlbench)
data("BostonHousing")
BostonHousing
choose <- c('crim', 'rm', 'dis', 'tax', 'medv')
myds <- BostonHousing[,chosse]
head(choosen)
grp <- c()
nrow(myds)
for(i in 1:nrow(myds)){
  if(myds$medv[i]>=25.0){
    grp[i] <- "H"
  }else if(myds$medv[i]<=17.0){
    grp[i] <- "L"
  }else{
    grp[i] <- "M"
  }
}
grp
grp <- factor(grp, levels=c("H","M","L"))
grp
myds <- data.frame(myds, grp)
head(myds)

par(mfrow=c(2,3))
for(i in 1:5){
  hist(myds[,i], main=colnames(myds)[i], col="yellow")
}

par(mfrow=c(2, 3))
for(i in 1:5){
  boxplot(myds[,i], main=colnames(myds)[i], col="yellow")
}

point <- as.numeric(myds$grp)
color <- c('red', 'green', 'blue')
pairs(myds[,-6], col=color[point], pch=point)

cor(myds[,-6])

library(car)
newdata <- Prestige[,c(1:4)]
newdata
pairs(newdata, col='blue', pch=16, main='Matrix Scatterplot')
mod <- lm(income~education+prestige+women, data=newdata)
summary(mod)

pred <- predict(mod, Prestige[,c('education', 'prestige', 'women')])
pred
pred[order(pred, decreasing=T)]
compare <- data.frame(pred, Prestige[,2], pred-Prestige[,2])
colnames(compare) <- c('예상 값', '실제 값', '오차')
head(compare)

library(MASS)                 # stepAIC( ) 함수 제공
newdata2 <- Prestige[,c(1:5)] # 모델 구축에 사용할 데이터셋 생성
head(newdata2)
mod2 <- lm(income ~ education + prestige + women + census, data= newdata2)
summary(mod2)           # 다중회귀모델
mod3 <- stepAIC(mod2)   # 변수 선택 진행
mod3                    # 변수 선택 후 결과 확인
summary(mod3)           # stepAIC() 적용

iris.new <- iris
iris.new$Species <- as.integer(iris.new$Species) # 범주형 자료를 정수로 변환
head(iris.new)
mod.iris <- glm(Species ~., data=iris.new)       # 로지스틱 회귀모델 도출
summary(mod.iris)                                # 회귀모델의 상세 내용 확인

mod2 <- stepAIC(mod.iris)
summary(mod2)

# 예측 대상 데이터 생성(데이터프레임)
unknown <- data.frame(rbind(c(5.1, 3.5, 1.4, 0.2))) # rbind 대신 t() 써도 됨
names(unknown)
names(unknown) <- names(iris)[1:4] # 예측 대상 데이터
unknown
pred <- predict(mod.iris, unknown) # 품종 예측
pred                               # 예측 결과 출력
round(pred,0)                      # 예측 결과 출력(소수 첫째 자리에서 반올림)

# 실제 품종명 알아보기
pred <- round(pred,0)
pred
levels(iris$Species)
levels(iris$Species)[pred]

test <- iris[,1:4]                 # 예측 대상 데이터 준비
test
pred <- predict(mod.iris, test)    # 모델을 이용한 예측
pred <- round(pred,0)
pred                               # 예측 결과 출력
answer <- iris.new$Species         # 실제 품종 정보
pred == answer                     # 예측 품종과 실제 품종이 같은지 비교
acc <- mean(pred == answer)        # 예측 정확도 계산
acc                                # 예측 정확도 출력






# 11 머신러닝 비지도 등

library(MASS)
data("birthwt")
str(birthwt)
birthwt
for(i in 1:10){
  print(typeof(birthwt[,i]))
}

set.seed(1234) # 무작위(Random) 결과를 언제나 똑같이 나오게 고정
tar <- sample(1:nrow(birthwt),round(nrow(birthwt)*0.7))
train <- birthwt[tar, ]
str(train)
test <- birthwt[-tar, ]
str(test)
fit<-lm(low ~ ., data=train)
fit2 <- stepAIC(fit)
result <- predict(fit2, test)

test[,1]==round(result)
mean(test[,1]==round(result))

data(iris)
train <- iris[,-5]
str(train)
# 1
for(i in 1:4)
  print(typeof(train[,i]))
# 2
ff <- kmeans(train, centers=3, iter.max=100)
ff

# 3
train2 <- scale(train)
ff3 <- kmeans(train2, centers=3, iter.max=100)
ff3
#왜 Scale을 했는데 결과가 더 나쁠까?  이것은 Iris 데이터셋의 특성 때문입니다.
# 단위가 같음: Iris 데이터는 네 가지 변수 모두 cm 단위로 측정되었습니다. 애초에 키(cm)와 몸무게(kg)처럼 물리적 단위가 다르지 않습니다.
# 분산 자체가 정보: Iris 데이터는 꽃잎 길이(Petal.Length)의 차이가 매우 커서 이것이 품종을 구분하는 가장 강력한 힌트(Signal)가 됩니다. 반면 꽃받침 너비(Sepal.Width)는 품종 간 차이가 별로 없는 소음(Noise)에 가깝습니다.
# Scale의 부작용: scale()을 하면 모든 변수의 영향력을 똑같이(표준편차 1) 만들어 버립니다.
# 결과: 품종을 잘 구분해주던 Petal.Length의 강력한 힘은 줄어들고, 별로 도움 안 되는 Sepal.Width의 목소리가 커져버린 셈입니다.


# 12 그래프 함수 II
library(ggplot2)
head(sleep)
ggplot(data=sleep, aes(x=ID, y=extra))+
  geom_col(fill="yellow", colour="black")+
  ggtitle("수면제의 약물효과")+
  xlab("환자번호")+
  ylab("효과")

month <- c(1,2,3,4,5,6)
rain <- c(55,50,45,50,60,70)
df <- data.frame(month,rain) # 그래프를 작성할 대상 데이터
df
ggplot(df, aes(x=month,y=rain)) + # 그래프를 그릴 데이터 지정
  geom_bar(stat="identity", # 막대의 높이는 y축에 해당하는 열의 값
           width=0.7, # 막대의 폭 지정
           fill="steelblue") # 막대의 색 지정

ggplot(df, aes(x=month,y=rain)) + # 그래프를 그릴 데이터 지정
  geom_bar(stat="identity", # 막대 높이는 y축에 해당하는 열의 값
           width=0.7, # 막대의 폭 지정
           fill="steelblue") + # 막대의 색 지정
  ggtitle("월별 강수량") + # 그래프의 제목 지정
  theme(plot.title = element_text(size=25, face="bold", colour="steelblue")) +
  labs(x="월",y="강수량") + # 그래프의 x, y축 레이블 지정
  coord_flip( ) # 그래프를 가로 방향으로 출력

library(ggplot2)
head(diamonds)
# 누적 막대그래프 작성, 투명도 체크
ggplot(diamonds, aes(x=clarity)) + geom_bar() # fill 없으면 그냥 막대 구분없이 출력
ggplot(diamonds, aes(x=clarity, fill=cut)) + geom_bar()
# 그룹화 막대그래프 작성
ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar( position = 'dodge' )
# 비율 중첩 막대그래프 작성
ggplot(diamonds, aes(color, fill=cut)) + geom_bar(position='fill')
# 가로 중첩 막대그래프 작성
ggplot(diamonds, aes(color, fill=cut)) + geom_bar(position='fill') + coord_flip()

library(dplyr)
sum_diamonds <- group_by(diamonds, cut) %>%
  summarise(mean_price=mean(price), mean_table=mean(table),median_depth=median(depth), n=n()) # n(): 각 묶음(그룹) 안에 데이터가 몇 줄 들어있는지 셉니다.
sum_diamonds

# 누적 파이 차트 작성
ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar() + coord_polar()
# 그룹화 파이 차트 작성
ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar( position = 'dodge' ) + coord_polar()
# 비율 누적 파이 차트 작성
ggplot(diamonds, aes(color, fill=cut)) + geom_bar(position='fill') + coord_polar()
# 원통형 파이 차트 작성
ggplot(diamonds, aes(color, fill=cut)) + geom_bar() + coord_polar(theta ="y", start=0)

head(economics)
# 시계열 그래프 작성, 1967~ 2014년 미국 경제관련 데이터
ggplot(data=economics, aes(x=date, y=unemploy)) + geom_line()
# 90도 돌리는 2가지 방법
ggplot(data=economics, aes(date, unemploy)) + geom_line() + coord_flip()
ggplot(economics, aes(unemploy, date)) + geom_line(orientation = "y")
# 다중 선그래프 작성
economics_long
table(economics_long$variable)
ggplot(economics_long, aes(x=date, y=value01, fill = variable)) + geom_line() # line에선 fill대신 color를 사용
ggplot(economics_long, aes(x=date, y=value01, color = variable)) + geom_line()
# 2000년도 이전 데이터
y20 <- subset(economics, economics$date < as.Date("2000-01-01"))
ggplot(y20, aes(date, pop)) + geom_line()

# 그래픽 패키지 불러오기
library(ggplot2)
economics_long
# 누적 영역 그래프 작성
par(mfrow=c(1, 2))
ggplot(economics_long, aes(date, value01)) + geom_area() # 마찬가지로 fill 안 넣으면 이상한 놈 나옴
ggplot(economics_long, aes(date, value01, fill=variable)) + geom_area()
ggplot(economics_long, aes(date, value01)) + geom_area(aes(fill=variable)) # 이렇게도 됨
library(dplyr)
economics_sum <- economics_long %>%
  group_by(date, variable) %>%
  summarise(n = sum(value01)) %>% # value01을 기준으로 / value는 사용 안 함
  mutate(percentage = n / sum(n))
economics_sum
# 비율 누적 영역 그래프
# 위에 계산해서 써도 되는데
ggplot(economics_sum, aes(date, percentage, fill=variable)) + geom_area(alpha=0.6, size=1, colour="white")
# 이것도 geom_bar처럼 position=fill 됨 ㅅㅂ 왜한거야
ggplot(economics_long, aes(date, value01, fill=variable)) + geom_area(position="fill", alpha=0.6, size=1, colour="white")

head(iris)
# 산포도 작성
ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width) ) +
  geom_point()
# 마커 포함 산포도 작성
ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width) ) +
  geom_point(aes(color=Species, shape=Species), size=3)
# 똑같은거 이렇게 해도 됨
ggplot(data=iris, aes(x = Sepal.Length, y = Sepal.Width, color=Species, shape=Species) ) +
  geom_point(size=3)

library(ggplot2)
data(mpg)
mpg
# 박스 플롯 시각화
ggplot(mpg, aes(class, hwy)) + geom_boxplot() # 차종마다 4륜, 전륜, 후륜 안 나누고 합함
# 색상 박스 플롯 시각화 (차종마다 전륜, 후륜, 4륜 나눔)
# fill로 해도 비슷함
ggplot(mpg, aes(class, hwy)) + geom_boxplot(aes(colour = drv))
ggplot(mpg, aes(class, hwy)) + geom_boxplot(aes(fill = drv))

ggplot(iris, aes(x=Petal.Length)) + # 그래프를 그릴 데이터 지정
  geom_histogram(binwidth=0.5) # 히스토그램 작성
# 색상 구분 추가
ggplot(iris, aes(x=Sepal.Width, fill=Species, color=Species)) +
  geom_histogram(binwidth = 0.5) +
  theme(legend.position="top")
#dodge 시키기(쌓아놓지 말고 옆으로 비켜), fill이 있으면 color 사실 필요 없음
ggplot(iris, aes(x=Sepal.Width, fill=Species)) +
  geom_histogram(binwidth = 0.5, position="dodge") +
  theme(legend.position="top")

head(mtcars)
mosaicplot(~gear+vs, data = mtcars, color=TRUE,
           main ="Gear and Vs")
mosaicplot(~gear+vs, data = mtcars, color=c("green","blue"), main ="Gear and Vs")

st <- data.frame(state.x77) # 매트릭스를 데이터프레임으로 변환
symbols(st$Illiteracy, st$Murder, # 원의 x, y 좌표의 열
        circles=st$Population, # 원의 반지름의 열
        inches=0.3, # 원의 크기 조절값
        fg="white", # 원의 테두리 색
        bg="lightgray", # 원의 바탕색
        lwd=1.5, # 원의 테두리선 두께
        xlab="rate of Illiteracy",
        ylab="crime(murder) rate",
        main="Illiteracy and Crime")
text(st$Illiteracy, st$Murder, # 텍스트가 출력될 x, y 좌표
     rownames(st), # 출력할 텍스트
     cex=0.6, # 폰트 크기
     col="brown") # 폰트 컬러

library(treemap) # treemap 패키지 불러오기
data(GNI2014) # 데이터 불러오기
head(GNI2014) # 데이터 내용보기
treemap(GNI2014,
        index=c("continent","iso3"), # 계층구조 설정(대륙-국가)
        vSize="population", # 타일의 크기
        vColor="GNI", # 타일의 컬러
        type="value", # 타일 컬러링 방법
        title="World's GNI") # 트리맵 제목

st <- data.frame(state.x77) # 매트릭스를 데이터프레임으로 변환
st <- data.frame(st, stname=rownames(st)) # 주 이름 열 stname을 추가
treemap(st,
        index=c("stname"), # 타일에 주 이름 표기
        vSize="Area", # 타일의 크기
        vColor="Income", # 타일의 컬러
        type="value", # 타일 컬러링 방법
        title="USA states area and income" ) # 트리맵의 제목

# scale_x_log10, scale_y_log10 함수
gapminder
ggplot(gapminder, aes(gdpPercap, lifeExp, col=continent))+
  geom_point(alpha=0.2)
# 가로축을 로그 스케일로 변환
ggplot(gapminder, aes(gdpPercap, lifeExp, col=continent))+
  geom_point() + scale_x_log10()
# size 옵션을 활용하여 pop도 그래프에 표시
ggplot(gapminder, aes(gdpPercap, lifeExp, color=continent, size=pop))+
  geom_point() + scale_x_log10()
# facet_wrap 함수 추가
ggplot(gapminder, aes(gdpPercap, lifeExp, color=continent, size=pop))+
  geom_point() + scale_x_log10() + facet_wrap(~year)



# 연습

# iris 박스 플롯
ggplot(data=iris, aes(y=Petal.Length))+
  geom_boxplot(fill="yellow")
ggplot(iris, aes(y=Petal.Length, fill=Species))+
  geom_boxplot()

# airmiles 선 그래프 연습
year <- 1937:1960
cnt <- as.vector(airmiles)
df <- data.frame(year,cnt) # 데이터 준비
head(df)
ggplot(df, aes(year, cnt))+geom_line(color='red')

#geom_point gapminder 연습
ggplot(filter(gapminder, year==2007), aes(lifeExp, color=continent))+
  geom_histogram()
ggplot(filter(gapminder, year==2007), aes(lifeExp, color=continent))+
  geom_histogram(position="dodge")

#geom_boxplot 함수 사용
filter(gapminder, year==2007) %>% 
  ggplot(aes(continent, lifeExp, color=continent))+
    geom_boxplot()

# 연습 gapminder에서 한국(Korea, Rep.)의 연간 예상 수명을 그래프로 시각화
KOR <- filter(gapminder, country=="Korea, Rep.")
ggplot(KOR, aes(year, lifeExp, color=country))+
  geom_point() + geom_line()
head(gapminder)
# 연습 한국 강조하기
ggplot(gapminder, aes(gdpPercap, lifeExp, col=continent, size=pop))+
  geom_point()+facet_wrap(~year)+scale_x_log10()+
  geom_point(data = KOR, color = "black", shape = 1, stroke=1.5) +  
  geom_text(data = KOR, label = "Korea", color = "black", vjust = -1, size=3)