반응형

[R] 범주형 변수의 선형 회귀 분석 (Simple linear regression with categorical variable) - lm(), factor()

 

지난 포스팅에서 우리는 수축기 혈압(SBP)과 심혈관 질병 위험 점수 (CVD_RISK)의 선형 회귀 분석에 대해 알아보았다.(2022.12.22 - [선형 회귀 분석/R] - [R] 단순 선형 회귀 분석 (Simple linear regression) - lm()) 이 분석에 쓰인 독립 변수인 수축기 혈압 (SBP)는 연속형 변수다. 만약 범주형 변수로 선형 회귀 분석을 시행하려 한다면 어떻게 해야 할까? 예를 들어 흡연 여부(SMOK: 비흡연자 or 과거 흡연자 or  현재 흡연자)로 심혈관 위험 점수를 예측하려 할 땐 어떻게 해야 할까? 이번 포스팅에서는 이에 대해 알아볼 것이다.

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.12.18)

 

분석용 데이터 (update 22.12.18)

2022년 12월 18일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 범주형 자료 분석 - 모평균 검정 - 상관분석 - 반복 측정 자료

medistat.tistory.com

 

코드를 보여드리기에 앞서 워킹 디렉토리부터 지정하겠다.

워킹 디렉토리에 관한 설명은 다음 링크된 포스트에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 작업 디렉토리 (Working Directory) 지정 - getwd(), setwd()

setwd("C:/Users/user/Documents/Tistory_blog")

 

데이터를 불러와 df에 객체로 저장하겠다.

데이터 불러오는 방법은 다음 링크에서 볼 수 있다.

2022.08.05 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : EXCEL - read_excel(), read.xlsx()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 저장하기 : CSV 파일 - write.csv(), write_csv()

2022.08.10 - [통계 프로그램 사용 방법/R] - [R] 데이터 불러오기 : SAS file (.sas7bdat) - read.sas7bdat(), read_sas()

install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

 

목표:  흡연 여부(SMOK)로 심혈관 위험 점수(CVD_RISK)를 예측할 수 있는가?

이전 단순 선형 회귀 분석에서 배운 대로 선형 회귀 분석을 시행하면 어떻게 될까? 자료의 유형 (연속형 vs 범주형)을 고려하지 않은 책 우선 분석을 시행해보자. 분석 방법은 이전 포스팅(2022.12.22 - [선형 회귀 분석/R] - [R] 단순 선형 회귀 분석 (Simple linear regression) - lm())을 보면 알 수 있다.

 

코드

LR_SMOK_CVD_ft<-lm(CVD_RISK~SMOK, data=df)
summary(LR_SMOK_CVD_ft)

 

결과

Call:
lm(formula = CVD_RISK ~ SMOK, data = df)

Residuals:
    Min      1Q  Median      3Q     Max 
-45.581 -11.818  -0.802  11.130  54.669 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 159.9106     0.7216  221.61   <2e-16 ***
SMOK         15.2974     0.6421   23.82   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.45 on 998 degrees of freedom
Multiple R-squared:  0.3626,	Adjusted R-squared:  0.3619 
F-statistic: 567.6 on 1 and 998 DF,  p-value: < 2.2e-16

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept) 159.9106     0.7216  221.61   <2e-16 ***
SMOK           15.2974     0.6421   23.82   <2e-16 ***

 

주목해야할 건 "SMOK"이다. 이전 연속형 독립 변수로 시행한 선형 회귀 분석의 결과 해석은 "독립 변수가 1 단위 증가할 때 종속 변수의 변화량"="기울기"이다. 그러면 이 결과를 해석하면 어떻게 될까? 참고로 SMOK는 다음과 같은 변수다.

SMOK 해석
0 비흡연자
1 과거 흡연자
2 현재 흡연자

 SMOK가 1단위 증가할 때 CVD_RISK의 변화량은 "비흡연자에 비해 과거 흡연자가", "과거 흡연자에 비해 현재 흡연자가" 얼마나 더 높은 CVD_RISK의 값을 갖는지 표현하는 것이다. 근데 이 값은 15.2974로 같다. 즉, 비흡연자에서 과거 흡연자로 변하는 것과, 과거 흡연자에서 현재 흡연자로 변화하는 것이 같은 수준이라고 가정하고 있는 것이다. 이 말은 SMOK를 등간척도로 보고 있다는 말이다. 등간척도는 연속 변수의 일종이니, R은 현재 SMOK를 연속변수로 확인하고 있다는 것이다. 과연 R이 SMOK를 연속변수로 확인하고 있는지 확인해 보자. (변수의 유형을 확인하는 방법은 다음 링크에서 확인할 수 있다.2022.11.21 - [통계 프로그램 사용 방법/R] - [R] 변수의 유형 (타입, type) 확인 및 변경 - as.factor(), as.numeric(), as.character(), str())

코드

str(df$SMOK)

결과

num [1:1000] 1 2 0 0 2 1 1 1 1 0 ...

역시나 numeric (연속형 변수)로 인지하고 있다. 그도 그럴 것이 0,1,2로 구성된 변수를 R이 무슨 수로 범주형 변수인지, 연속형 변수인지 알겠는가. 따라서 우리가 직접 지정해주어야만 한다. 범주형 변수로 변환시켜 주겠다. 변수의 유형을 변환하는 방법에 대해서는 다음 링크(2022.11.21 - [통계 프로그램 사용 방법/R] - [R] 변수의 유형 (타입, type) 확인 및 변경 - as.factor(), as.numeric(), as.character(), str())에서 확인할 수 있다. 이 링크의 말미에 간단히 언급한 factor() 함수를 사용할 것이다.

 

코드

df$SMOK<-factor(df$SMOK)

 

코드

이제 다시 단순 선형 회귀 분석을 시행해보자.

LR_SMOK_CVD<-lm(CVD_RISK~SMOK, data=df)
summary(LR_SMOK_CVD)

결과

Call:
lm(formula = CVD_RISK ~ SMOK, data = df)

Residuals:
   Min     1Q Median     3Q    Max 
-47.33 -11.61  -0.49  10.87  55.23 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 159.3539     0.7629  208.88   <2e-16 ***
SMOK1        17.6012     1.2229   14.39   <2e-16 ***
SMOK2        30.0866     1.3021   23.11   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.42 on 997 degrees of freedom
Multiple R-squared:  0.3657,	Adjusted R-squared:  0.3644 
F-statistic: 287.4 on 2 and 997 DF,  p-value: < 2.2e-16

Coefficients:
                      Estimate  Std. Error t value Pr(>|t|)    
(Intercept)  159.3539     0.7629  208.88   <2e-16 ***
SMOK1           17.6012     1.2229     14.39   <2e-16 ***
SMOK2         30.0866     1.3021      23.11   <2e-16 ***

 

결과를 보면 범주형 변수로 바꾸기 전과 다르게, SMOK에 대한 결괏값이 2개가 나온다. SMOK1과 SMOK2다. SMOK는 0,1,2 세 개의 값을 갖는데, SMOK=1인 그룹과 SMOK=2인 그룹에 대한 통계 검정 결과를 나타내는 것이다. 그렇다면 왜 0은 없을까? 0은 참조값(reference)으로 쓰인 것이다. 즉 비흡연자(SMOK=0)에 비해 과거 흡연자 (SMOK=1)는 심혈관 질환 위험 점수 (CVD_RISK)가 17.6012점 높으며, p-value는 매우 작으므로 이는 유의미한 차이라고 할 수 있다. 또한, 비흡연자(SMOK=0)에 비해 현재 흡연자 (SMOK=2)는 심혈관 질환 위험 점수 (CVD_RISK)가 30.0866점 높으며, p-value는 매우 작으므로 이는 유의미한 차이라고 할 수 있다. 

 

 R은 가장 작은 값을 자동으로 참조값으로 잡는다. 그래서 SMOK=0인 비흡연자가 reference로 잡혔다. 만약, 참조값(reference)으로 비흡연자가 아닌 다른 군을 지정하고 싶다면 어떻게 할까? 바로, 범주형 변수로 지정할 때, levels라는 argument의 맨 앞자리에 원하는 숫자를 적으면 된다. 만약 과거 흡연자 (SMOK=1)를 reference로 잡고자 한다면, levels=c(1,0,2)와 같이 적으면 된다. 마지막 0과 2의 순서는 바뀌어도 reference와는 아무 상관이 없고, 다만 선형 회귀 분석 결과가 나타나는 순서를 지정하는 역할만 한다. 다음 예시를 보자.

 

코드

#범주형 변수 지정
df$SMOK<-factor(df$SMOK, levels=c(1,0,2))

#선형회귀분석 시행
LR_SMOK_CVD<-lm(CVD_RISK~SMOK, data=df)
summary(LR_SMOK_CVD)

 

결과

Call:
lm(formula = CVD_RISK ~ SMOK, data = df)

Residuals:
   Min     1Q Median     3Q    Max 
-47.33 -11.61  -0.49  10.87  55.23 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 176.9552     0.9557  185.15   <2e-16 ***
SMOK0       -17.6012     1.2229  -14.39   <2e-16 ***
SMOK2        12.4853     1.4237    8.77   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 16.42 on 997 degrees of freedom
Multiple R-squared:  0.3657,	Adjusted R-squared:  0.3644 
F-statistic: 287.4 on 2 and 997 DF,  p-value: < 2.2e-16

SMOK0과 SMOK2에 대한 내용만 있고, SMOK1은 없어졌다. 만약 levels=c(1,2,0)이라고 적었다면 두 행의 순서가 뒤바뀌어 나왔을 것이다.

 

 

이분형 변수는 범주형 지정이 필요 없다.

이분형 변수는 범주형 변수로의 변환이 굳이 필요는 없다. 왜냐하면 어차피 값이 두 개밖에 존재하지 않기 때문에, 연속형이든 범주형이든 같은 결과를 내기 때문이다. 하지만 이 경우 반드시 reference가 0이 되므로 만약 1을 reference로 잡고 싶은 경우, 범주형 변수로 변경하며 reference를 지정해주면 된다.

 

코드 정리

##워킹 디렉토리 지정
setwd("C:/Users/user/Documents/Tistory_blog")

##데이터 불러오기
install.packages("readr")
library("readr")
df<-read_csv("Data.csv")

##범주형 지정
df$SMOK<-factor(df$SMOK)

##선형 회귀 분석 시행
LR_SMOK_CVD<-lm(CVD_RISK~SMOK, data=df)
summary(LR_SMOK_CVD)

 

[R] 범주형 변수의 선형 회귀 분석 (Simple linear regression with categorical variable) 정복 완료!

작성일: 2022.12.22.

최종 수정일: 2022.12.22.

이용 프로그램: R 4.2.2

RStudio v2022.07.2

RStudio 2022.07.2+576 "Spotted Wakerobin" Release

운영체제: Windows 10, Mac OS 12.6.1

반응형

+ Recent posts