기타문서
[R] 상관 관계 분석, 선형 회귀 분석, 다중 회귀 분석, 로지스틱 회귀 분석
Mosu(정종인)
2022. 12. 12. 17:12
반응형
library 설치
install.packages("car")
install.packages("descr")
install.packages('agricolae')
install.packages("nparcomp")
install.packages("survival")
install.packages("Rcmdr")
require(nparcomp)
require(stats)
library(Rcmdr)
library(survival)
library(nparcomp)
library(agricolae)
library(descr)
library(car)
데이터를 받으면 바탕화면으로 빼고, rstudio로 연다. comma로 나뉘어져 있으면 sep만 ,로 바꿔주자.
dat<-read.table(file="C:/Users/cse/Desktop/~~~~.txt",header=TRUE,sep="\t",fill=TRUE)
결측값을 제거 해준다.
# NA 가 있는 행 제거
dat1<-dat1[complete.cases(dat1),]
# NA 값을 0으로 변경
dat1[is.na(dat1)]<-0
# NA 제거
data1<-na.omit(colon)
문제에서 그룹을 나누라고 했으면 그룹을 먼저 나누어준다. ifelse 문으로 나누어줄 수 있다.
dat$grp<-ifelse(dat$group=="ctrl",0,1)
분포를 보고 아웃 라이어를 제거해준다.
# 분포
hist(dat$A)
hist(dat$A, breaks = seq(0, 10000, by=100))
# 산점도
plot(cars)
plot(dist ~ speed, data=cars)
lines(cars)
lines(lowess(cars))
# freq
freq(dat$A)
# 아웃라이어 제거
res <- res[res$A>0 & res$A<10000,]
res <- res[(res$grp!="trt2"),]
모수 검정 vs 비모수 검정
데이터가 5000 이상이면 정규분포에 가까워진다는 중심극한정리.
# shapiro test
shapiro.test(data$weight) ## p-value가 0.05보다 커야 정규분포
데이터가 정규분포하면 모수 검정, 아니면 비모수 검정으로 가자.
모수 검정
- t-test : 범주형(2군) vs 연속형 평균 비교
- A에 대해 두 그룹 간 유의미한 차이가 있는지?
- ANOVA : 범주형(3군) vs 연속형 평균 비교
- A에 대해 세 그룹 간 유의미한 차이가 있는지?
- 사후 검정 : TukeyHSD
- Pearson correlation : 연속형 vs 연속형 상관성
- A와 B에 상관관계가 있는지?
# bartlett test
bartlett.test(weight~group, data=data) ## 3개 그룹 퍼진 정도(분산) 검사
## p-value가 0.05보다 커야 분산이 같다는 의미.
# ANOVA
out = aov(HT ~ factor(F_BR_3), data=a)
summary(out)
## F값이 0.05보다 작으면 서로 다른 그룹 간 평균 차이가 유의미하다.
TukeyHSD(out)
plot(TukeyHSD(out))
# Pearson correlation
cor.test(cars$speed, cars$dist) # cor 값이 1에 가까울 수록 양의 상관관계에 있다.
# cor 값을 제곱하면 (cor^2) 선형 회귀 분석의 설명력이 된다.
비모수검정
- Mann-Whitney U test : 범주형 (2군) vs 연속형 중위수 비교
- A에 대해 두 그룹 간 유의미한 차이가 있는지?
- Wilcoxon-Signed rank test : 범주형(2군) vs 연속형 중위수 비교
- A에 대해 두 그룹 간 유의미한 차이가 있는지?
- kruskal-wallis test : 범주형(3군) vs 연속형 중위수 비교
- A에 대해 세 그룹 간 유의미한 차이가 있는지?
- 사후검정 : mctp
- Spearman Correlation : 연속형 vs 연속형 상관성
- A와 B에 상관관계가 있는지?
# wilcox test
wilcox.test(weight~gr, data=data1, exact=FALSE, conf.level=0.95)
# kruskal test
kruskal.test(weight ~ group, data=data)
result = mctp(weight ~ group, data=data)
summary(result)
## factor를 사용하지 않아도 괜찮다.
# Spearman Correlation
cor.test(cars$speed, cars$dist, method="spearman") # cor 값이 1에 가까울 수록 양의 상관관계에 있다.
선형 회귀 분석
영향을 주는 변수(x축, 독립 변수) : speed
영향을 받는 변수(y축, 종속 변수) : dist
(두 변수 모두 정규분포 해야 함)
우리가 알고 싶은 것? : speed에 따른 dist 변화
# simple regression, 둘 다 continuous일 때
res = lm(dist ~ speed, data=cars)
summay(res)
# simple regression, 영향을 주는 변수가 categorical (2 groups)일 때
res = lm(weight ~ factor(gr), data=data) ## 0과 1만 있다면 factor 안붙여도 됨
summary(res)
# simple regression, 영향을 주는 변수가 categorical (3 groups)일 때
res = lm(weight ~ factor(gr), data=data)
summary(res)
## weight = 5.03 -0.37 * gr1 + 0.49 * gr2
## 결과 분석 팁 : gr이 0일 때가 default라고 하자.
## gr이 1이라면 weight = 5.03 - 0.37
## gr이 2라면 weight = 5.03 + 0.49
## 즉, gr이 0일 때 비해 얼마나 차이가 나는지?
다중 회귀 분석
종속변수(y축) : mpg
독립변수(x축) : wt, vs, gear
res = lm(mpg ~ wt + vs + factor(gear), data=input())
summary(res)
step(res)
## AIC 오름차순으로 표가 나옴. AIC 값이 낮을수록 좋은 것.
## <none> 은 아무것도 안뺐을 때
## 앞에 붙는 +는 추가했을 때, -는 제거했을 때
## 현재보다 더 나은 것이 있으면 자동으로 함수를 실행.
# VIF Variance Inflation Factor : X들간 상관관계 분석
vif(res)
## gvif 값들이 10이하면 괜찮다고 생각. 10이 넘어가면 fomula에서 빼야 함.
# plot 그리기
vif_values <- vif(m)
barplot(vif_values, main="VIF Values", horiz=TRUE, col="steelblue")
abline(v=5, lwd=3, lty=2) # 위에 그린 barplot에 v=5인 점선을 그어준다.
Chi-Square 검정
두 범주형 변수간 관련성이 있는지 판별.
a4<-CrossTable(b$obstruct, b$status)
a4
# chi-square
## 관찰된 빈도가 기대되는 빈도와 의미있게 다른지의 여부를 검정하기 위해 사용되는 검정방법
chisq.test(b$obstruct, b$status)
## p-value가 0.05 이하면 두 변수간 관련성 O
Logistic Regression
종속변수가 categorical 변수일 때 적용. 정규분포를 따르지 않아도 됨.
result = glm(status~ sex + age + obstruct + perfor + adhere + nodes +
factor(differ) +
factor(extent) + surg, family=binomial, data=data1)
summary(result)
step(result)
step(result, direction="backward")
step(result, direction="forward")
Odds Ratio
실패에 비해 성공할 확률의 비.
0일 때 비해 1일 확률의 비
ORtable = function(x, digits=2){
suppressMessages(a<-confint(x))
result=data.frame(exp(coef(x)),exp(a))
result=round(result,digits)
result=cbind(result, round(summary(x)$coefficient[,4],3))
colnames(result)=c("OR", "2.5%", "97.5%", "p")
result
}
ORtable(m)
result = glm(status ~ obstruct , family=binomial, data=b)
summary(result)
ORtable(result)
# visualization of Odds Ratio
install.packages("moonBook")
library(moonBook)
odds_ratio = ORtable(m)
odds_ratio = odds_ratio[2:nrow(odds_ratio),]
HRplot(odds_ratio, type=2, show.CI=TRUE, cex=2)

해석 : 장이 폐쇄되지 않았을 때 비해서 장이 폐쇄된 경우는 odds ratio배(1.26배)만큼 status확률(재발 또는 사망 확률)이 증가한다. 1에 걸쳐있으면 유의성이 떨어진다고 본다.
해석2 : 암세포가 침습한 깊이가 4(adjacent organ, 장기와 인접)했을 때는 깊이가 1일때 비해 status확률이 4.83배 증가한다.
Logistic 회귀 부분 전체 코드
################################## categorical data analysis ##################################
# dependent var : status ( recur or death of colorectal cancer =1 )
# independent var :
obstruct : obastruction 종양에 의한 장의 폐쇄
install.packages("survival")
library(survival)
str(colon)
View(colon)
library(descr)
b<-colon
#1. categorical variable : frequency
a1<-freq(b$status)
a1
View(a1)
a2<-freq(b$obstruct)
a2
View(a2)
a3<-table(b$obstruct, b$status)
a3
View(a3)
install.packages("Rcmdr")
library(Rcmdr)
rowPercents(a3)
colPercents(a3)
a4<-CrossTable(b$obstruct, b$status)
a4
#2. chi-sqaure test
chisq.test(b$obstruct, b$status)
# dependent var : status ( recur or death of colorectal cancer =1 )
# independent var :
obstruct : obastruction 종양에 의한 장의 폐쇄
perfor : perforation 장의 천공
adhere : adherence 인접장기와의 유착
nodes : number of lymphatic gland 암세포가 확인된 림프절 수
differ : 암세포의 조직학적 분화정도(1=well, 2=moderate, 3=poor)
extent : 암세포가 침습한 깊이 (1=submucosa, 2=muscle, 3=serosa, 4=adjacent organ)
surg : time until registration after surgery (0=short, 1=long)
freq(b$obstruct)
freq(b$perfor)
freq(b$adhere)
freq(b$nodes) # NA's 36
hist(b$nodes)
summary(b$nodes)
hist(b$nodes, breaks=seq(0,35, by=1))
freq(b$differ) # NA's 46
freq(b$extent)
freq(b$surg)
#2. chi-sqaure test
CrossTable(b$obstruct, b$status)
chisq.test(b$obstruct, b$status)
CrossTable(b$perfor, b$status)
chisq.test(b$perfor, b$status)
CrossTable(b$adhere, b$status)
chisq.test(b$adhere, b$status)
CrossTable(b$differ, b$status)
chisq.test(b$differ, b$status)
CrossTable(b$extent, b$status)
chisq.test(b$extent, b$status)
CrossTable(b$surg, b$status)
chisq.test(b$surg, b$status)
# continuous var -> categorical var
b$nodes_gr=ifelse(b$nodes>2,1,0)
CrossTable(b$nodes_gr, b$status)
chisq.test(b$nodes_gr, b$status)
###### logistic regression model #########################################
# GLM (Genelized Linear Model)
result = glm(status~ sex + age + obstruct + perfor + adhere + nodes + differ +
extent + surg, family=binomial, data=b)
summary(result)
dim(b)
data1<-na.omit(colon)
dim(data1)
# sample = data1
result = glm(status~ sex + age + obstruct + perfor + adhere + nodes + differ +
extent + surg, family=binomial, data=data1)
summary(result)
# differ, extent => gr
result = glm(status~ sex + age + obstruct + perfor + adhere + nodes +
factor(differ) +
factor(extent) + surg, family=binomial, data=data1)
summary(result)
step(result)
step(result, direction="backward")
step(result, direction="forward")
m=step(result, direction="backward")
summary(m)
m=step(result, direction="forward")
m=step(result, direction="both")
# Odds Ratio
ORtable = function(x, digits=2){
suppressMessages(a<-confint(x))
result=data.frame(exp(coef(x)),exp(a))
result=round(result,digits)
result=cbind(result, round(summary(x)$coefficient[,4],3))
colnames(result)=c("OR", "2.5%", "97.5%", "p")
result
}
ORtable(m)
# sex + age + obstruct + perfor + adhere + nodes + differ + extent + surg
result = glm(status ~ obstruct , family=binomial, data=b)
summary(result)
ORtable(result)
result = glm(status ~ adhere , family=binomial, data=b)
summary(result)
ORtable(result)
result = glm(status ~ nodes , family=binomial, data=b)
summary(result)
ORtable(result)
result = glm(status ~ factor(extent) , family=binomial, data=b)
summary(result)
ORtable(result)
result = glm(status ~ surg , family=binomial, data=b)
summary(result)
ORtable(result)
# visualization of Odds Ratio
install.packages("moonBook")
library(moonBook)
odds_ratio = ORtable(m)
odds_ratio = odds_ratio[2:nrow(odds_ratio),]
HRplot(odds_ratio, type=2, show.CI=TRUE, cex=2)
반응형