시각화¶
EDA 연습¶
상관관계가 높은 변수쌍 찾기¶
Data set - mtcars - R 기본 내장¶
- Motor Trend Car Road Test
- Motor Trend 잡지로 부터 추출된 자료
- 1973~1974년도 각기 종류가 다른 32대의 자동차 자료
- mpg(Miles/gallon) : 연비
- cyl(Number of cylinders) : 실린더 수
- disp(Displacement) : 배기량
- hp(Gross horsepower) : 마력
- drat(Rear axle ratio) : 후방 차축 비율
- wt(Weight) : 차체 무게
- qsec (1/4 mile time) : 400m 까기 걸리는 시간
- vs(V/S)
- am (Transmission 0 = auto, 1 = manual)
- gear (Number of forward gears) : 전진장치 개수
- carb (Number of carburetors) : 기화기 수
In [2]:
# 데이터 로드
# mtcars R
df <- mtcars
head(df)
In [4]:
str(df)
# 11개의 변수 32개의 데이터
In [5]:
# 모든 변수 산점도 그리기
plot(df[,c(1:5)])
plot(df[,c(6:11)])
In [6]:
# 위 산점도 분석 결과 mpg~disp 상관관계가 있어보이므로 따로 그려보기
plot(df$mpg ~ df$disp)
In [8]:
# 상관계수 구하기 - 상관계수 높음, 두 변수 좀 더 자세히 분석
# -1 < 상관계수 < 1
cor(df$mpg, df$disp)
In [10]:
# mpg 아웃라이어 확인
boxplot(df$mpg)
# 아웃라이어는 없고 데이터가 위쪽에 좀 더 분포되어 있음
In [13]:
# 히스토그램 - 분산 상태 확인
hist(df$mpg)
In [14]:
# 히스토그램 - 분산 상태 확인 2
hist(df$mpg, breaks = 10)
In [15]:
# disp 아웃라이어 확인
boxplot(df$disp)
# 아웃라이어는 없고 110~320에 몰려있음
In [16]:
# 히스토그램
hist(df$disp)
mpg, disp¶
- 두 변수 모두 이상점 없음
- 두 변수 상관관계가 있음을 방해하는 요소는 없어 보임
- 확증을 하기 위해서는 가설검증과 회귀분석 진행
- EDA 단계는 증거를 수집하고 특징을 찾는 것
다이아몬드 데이터 분석하기 - 가격에 영향을 미치는 것은?¶
DataSet - diamonds¶
- ggplot2 패키지에 포함
- 캐럿, 가격, 컷팅방법, 컬러등 다이아몬드 정보
In [17]:
library('ggplot2')
In [19]:
# 데이터 로드
df <- diamonds
str(df)
# tibble의 형태로 데이터 저장되어 있음
In [25]:
# 관측치가 많아 data 임의갯수 추출 - sample(10,2) 10개 중 2개 추출
Sample <- df[sample(nrow(df), 300),] # 53940개 중 300개 추출
attach(Sample)
In [26]:
str(Sample)
In [27]:
# 가격 분석
boxplot(price)
In [28]:
# 가격 이상치 - EDA로 원인 찾기
# price와 관련된 그래프 그리기
par(mfrow = c(3,3))
plot(data=Sample, price~.) # y축(종속변수) price
In [29]:
# price에 carat, x, y, z 등이 영향이 있어 보임
par(mfrow = c(2,2))
plot(price~carat + x + y + z)
In [30]:
# 상관 계수 구하기
Sample2 <- data.frame(price, carat, x, y ,z)
cor(Sample2)
¶
- price에 carat, y, x, z 순으로 영향을 미치는 것으로 보임
- x, y는 상관계수 거의 1
- 원인을 찾는 것이 더 어려움, 잠정적 결론
- EDA는 결론보다 탐색하면서 궁금증을 가지고 원인을 찾는 것
In [31]:
# price, carat, x 특징 파악
par(mfrow = c(1,3))
boxplot(price, main='price')
boxplot(carat, main='carat')
boxplot(x, main='x')
price, carat에 이상치가 많음 -> carat이 price에 이상치가 생기도록 영향을 미쳤을 수 있음¶
In [32]:
# carat 오름차순 정렬
reCarat <- carat[order(carat)]
par(mfrow = c(1,1))
plot(reCarat)
¶
- carat 이 2차 함수와 비슷
- carat 이 올라갈수록 값이 급격히 커짐
- 이런 성향 때문에 이상치 발생 예상
In [45]:
# carat 값 급격히 커지는 부분 제거
Sample2 <- subset(Sample, subset = (Sample$carat < 0.3))
par(mfrow = c(1,2))
boxplot(Sample$carat, main='carat 0.3 포함')
boxplot(Sample2$carat, main='carat 0.3 미포함')
In [47]:
# 가격 분석 - 0.3 carat 넘으면 가격 이상치 발생
boxplot(Sample2$price)
자료를 탐색하고 의문점이 생기면 그 원인을 찾는 것이 탐색적 자료 분석 (EDA)¶
섬세한 그래프를 그려 데이터 분석하기 : ggplot()¶
In [48]:
# 데이터 확인
library('ggplot2')
library('ggthemes')
str(diamonds)
In [49]:
# x와 price 산점도 그리기
ggplot(diamonds, aes(x=x, y=price)) + geom_point()
In [51]:
# clarity 변수, 컬러에 추가
ggplot(diamonds, aes(x=x, y=price, colour=clarity)) + geom_point()
# clarity는 여러 값에 분포되어 있어 price에 영향은 없는 것으로 보임
# 노란색이 아래, 진한색이 위쪽으로 분포하면 가격에 영향이 있을 것임
In [52]:
# 테마 적용
ggplot(diamonds, aes(x=x, y=price, colour=clarity)) + geom_point() + theme_solarized_2()
In [54]:
# 데이터 겹침 조절 - alpha
ggplot(diamonds, aes(x=x, y=price, colour=clarity)) +
geom_point(alpha=0.03) +
guides(colour = guide_legend(override.aes = list(alpha=1))) +
theme_solarized_2()
In [56]:
# x축 범위 조절(3~9), 수평선으로 평균 표시 geom_hline()
ggplot(diamonds, aes(x=x, y=price, colour=clarity)) +
geom_point(alpha=0.03) +
geom_hline(yintercept=mean(diamonds$price), color="turquoise3", alpha=.8) +
guides(colour = guide_legend(override.aes = list(alpha = 1))) +
xlim(3,9) +
theme_solarized_2()
시계열 데이터, 라인 그래프로 나타내기¶
In [57]:
# 데이터 로드 - 간단한 시간대별 매출 자료
TS <- read.csv('R-ggagi-data/example_ts.csv')
str(TS)
head(TS)
In [59]:
# 시각화 geom_line()
ggplot(TS, aes(x=Date, y=Sales)) + geom_line()
In [61]:
# x 축에 날짜 모두 표시하기 - factor()
# group=1 하나의 라인으로 연속적으로 그릴 때 사용
ggplot(TS, aes(x=factor(Date), y=Sales, group=1)) + geom_line()
In [62]:
# 점 추가 geom_point()
ggplot(TS, aes(x=factor(Date), y=Sales, group=1)) + geom_line() + geom_point()
In [63]:
# 테마 적용
ggplot(TS, aes(x=factor(Date), y=Sales, group=1)) + geom_line() + geom_point() + theme_light()
In [64]:
# 디자인 값 변경
ggplot(TS, aes(x=factor(Date), y=Sales, group=1)) +
geom_line(colour="orange1", size=1) +
geom_point(colour="orangered2", size=4) +
theme_light()
In [65]:
# title, x, y 축 이름 추가
ggplot(TS, aes(x=factor(Date), y=Sales, group=1)) +
geom_line(colour="orange1", size=1) +
geom_point(colour="orangered2", size=4) +
xlab("년도")+ ylab("매출") + ggtitle("A기업 월별 매출") +
theme_light()
# x label, y label
dplyr 패키지로 데이터 선택해 그래프로 나타내기 : filter()¶
- ggplot2를 만든 Hadley Wickham 교수가 data.frame 객체를 쉽게 다루기 위해 만든 패키지
In [66]:
install.packages('dplyr')
In [67]:
library('dplyr')
library('ggplot2')
library('ggthemes')
In [71]:
# 데이터 로드 - 전국 인구조사 자료
DF <- read.csv('R-ggagi-data/example_population_f.csv')
DF <- DF[,-1] # 첫번째 열을 ID 숫자이므로 삭제
DF <- tbl_df(DF) # tbl_df ( tibble diff라고도 함 ) 데이터 프레임의 변형, dataframe + dplyr 속성추가
head(DF)
In [72]:
# 충청도 도시들의 인구 그래프 그리기 - filter() 조건 vs subset()
DF2 <- filter(DF, Provinces=='충청북도' | Provinces=='충청남도')
head(DF2)
In [73]:
# 그래프 그리기
Graph <- ggplot(DF2, aes(x=City, y=Population, fill=Provinces)) +
geom_bar(stat='identity') + theme_wsj()
Graph
In [75]:
# 오름차순 정렬 - reorder()
GraphReorder <- ggplot(DF2, aes(x=reorder(City, Population), y=Population, fill=Provinces))+
geom_bar(stat='identity') + theme_wsj()
GraphReorder
In [78]:
# 남자비율이 높고 1인가구가 많은 도시
DF3 <- filter(DF, SexRatio > 1, PersInHou < 2)
DF3
In [80]:
# 시각화
Graph <- ggplot(DF3, aes(x=City, y=SexRatio, fill=Provinces)) +
geom_bar(stat='identity') + theme_wsj()
Graph
dplyr 패키지로 데이터 만들고 그래프로 나타내기 - mutate()¶
In [89]:
library('dplyr')
library('ggplot2')
library('ggthemes')
In [90]:
# 데이터 로드 - 전국 인구조사 자료
DF <- read.csv('R-ggagi-data/example_population_f.csv')
DF <- DF[,-1] # 첫번째 열은 ID 숫자이므로 삭제
DF <- tbl_df(DF)
# tbl_df (tibble diff) 데이터 프레임의 변형, dataframe + dplyr 속성 추가
head(DF)
In [99]:
# 남녀 비율 문자로 나타내는 변수 추가 - mutate() vs cbind()
DF <- mutate(DF,
SexF = ifelse(SexRatio < 1, '여자 비율 높음',
ifelse(SexRatio > 1, '남자 비율 높음','남여 비율 같음')))
# if(조건, A, B) : 참 이면 A 아니면 B
head(DF)
In [102]:
# sexF 순서있는 변수로 변환
DF$SexF <- factor(DF$SexF)
DF$SexF <- ordered(DF$SexF, c('여자 비율 높음', '남여 비율 같음', '남자 비율 높음'))
In [103]:
# 경기도 데이터 적재
DF2 <- filter(DF, Provinces=='경기도')
In [105]:
# 시각화 - 경기도 남자 비율 높음
Graph <- ggplot(DF2, aes(x=City, y=(SexRatio-1), fill=SexF)) +
geom_bar(stat='identity') + theme_wsj()
Graph
In [106]:
# 서울 데이터 적재
DF3 <- filter(DF, Provinces=='서울특별시')
In [107]:
# 시각화 - 서울 여자 비율 높음
Graph2 <- ggplot(DF3, aes(x=City, y=(SexRatio-1), fill=SexF)) +
geom_bar(stat='identity') + theme_wsj()
Graph2
reshape2 패키지 melt()이용. 데이터 가공 후 그래프 나타내기¶
- melt() : 명목형 변수로 만들어 줌
In [124]:
library('dplyr')
library('ggplot2')
library('ggthemes')
library('reshape2')
In [125]:
# 데이터 로드 - 전국 인구조사 자료
DF <- read.csv('R-ggagi-data/example_population_f.csv')
DF <- DF[,-1]
DF <- tbl_df(DF)
head(DF)
In [126]:
# 도별 합계 - 도시별(group by) 계산 summarise() 합계 sum()
group <- group_by(DF, Provinces) # 도시별
DF2 <- summarise(group, SumPopulation=sum(Population), Male=sum(Male), Female=sum(Female))
DF2
In [127]:
# melt(DF2, measure.vars=바꿀 변수들) - 성별은 하나의 명목형 변수로 처리하고 싶을 때
DF3 <- melt(DF2, measure.vars = c('Male','Female'))
In [128]:
DF2
DF3
In [130]:
# 컬럼명 변경 - colnames
colnames(DF3)[3] <- 'Sex'
colnames(DF3)[4] <- 'Population'
head(DF3)
In [132]:
# 새 변수 추가(남녀 비율 추가) - mutate()
DF4 <- mutate(DF3, Ratio = Population/SumPopulation)
# round() 함수 사용해서 소숫점 몇 자리 까지 나타낼 지 설정
DF4$Ratio <- round(DF4$Ratio, 3)
head(DF4)
In [138]:
# 시각화
G1 <- ggplot(DF4, aes(x=Provinces, y=Ratio, fill=Sex)) +
geom_bar(stat='identity') +
# coord_cartesian(ylim=c(0.45, 0.55)) + # 0.45~0.55 범위만 확대해서 보자
theme_wsj()
G2 <- geom_text(aes(y=Ratio, label=Ratio), colour='white')
G1 + G2
In [139]:
# 시각화 - coord_cartesian() 부분 확대
G1 <- ggplot(DF4, aes(x=Provinces, y=Ratio, fill=Sex)) +
geom_bar(stat='identity') +
coord_cartesian(ylim=c(0.45, 0.55)) + # 0.45~0.55 범위만 확대해서 보자
theme_wsj()
G2 <- geom_text(aes(y=Ratio, label=Ratio), colour='white')
G1 + G2
In [140]:
# 비율값 위치 조정
DF4 <- mutate(DF4, Position = ifelse(Sex == 'Male', 0.475, 0.525))
head(DF4)
In [141]:
# 시각화 - geom_text()
G1 <- ggplot(DF4, aes(x=Provinces, y=Ratio, fill=Sex)) +
geom_bar(stat='identity') +
coord_cartesian(ylim = c(0.45, 0.55)) + theme_wsj()
G2 <- geom_text(aes(y=Position, label=Ratio), colour='white')
G1 + G2
클리블랜드 점 그래프 그리기¶
In [142]:
require("dplyr")
require("ggplot2")
require("ggthemes")
In [143]:
# 데이터 로드 - 전국 인구조사 자료
DF <- read.csv('R-ggagi-data/example_population_f.csv')
DF <- DF[,-1]
DF <- tbl_df(DF)
head(DF)
In [144]:
# 남녀비율 명목형 변수로 만들기
DF2 <- mutate(DF, SexF = ifelse(SexRatio > 1, '남자 비율 높음',
ifelse(SexRatio == 1, '남녀 비율 같음', '여자 비율 높음')))
In [145]:
# 경기도 데이터 적재
DF3 <- filter(DF2, Provinces=='경기도')
In [146]:
# 시각화 - geom_segment()
# x 축 시작위치 : xend = 0, y축 명목형 변수 : yend = City
Graph <- ggplot(DF3, aes(x=(SexRatio-1), y=reorder(City, SexRatio))) +
geom_segment(aes(yend=City), xend=0, colour='grey50') +
geom_point(size=4, aes(colour=SexF)) + theme_minimal()
Graph
시간에 따른 연령별 인구 변화 그래프 그리기¶
- DataSet : 통계청 사이트에서 Download (www.kosis.or.kr)
In [147]:
library("dplyr")
library("ggplot2")
library("ggthemes")
library("reshape2")
library("scales") # 2e_07 => 200,000 표시
In [148]:
# 데이터 로드 - 시간별 인구변화 자료
DF <- read.csv('R-ggagi-data/example_population2.csv')
DF <- tbl_df(DF)
In [149]:
head(DF)
In [150]:
# 남녀를 합쳐 새로운 dataframe 생성
# 5세 => 10세 단위로 변경
group <- group_by(DF, Time)
DF2 <- summarise(group, s0=sum(age0to4, age5to9),
s10=sum(age10to14, age15to19),
s20=sum(age20to24, age25to29),
s30=sum(age30to34, age35to39),
s40=sum(age40to44, age45to49),
s50=sum(age50to54, age55to59),
s60=sum(age60to64, age65to69),
s70=sum(age70to74, age75to79),
s80=sum(age80to84, age85to89),
s90=sum(age90to94, age95to99),
s100=sum(age100to104, age105to109))
In [151]:
head(DF2)
In [154]:
# melt() -여러 컬럼으로 나열된 측정치들을 variable, value의 두 개 컬럼을 사용해
# 여러 행으로 변환하는 것이 melt( )의 역할
DF3 <- melt(DF2, measure.vars = c('s0', 's10', 's20', 's30', 's40', 's50',
's60', 's70', 's80', 's90', 's100'))
head(DF3)
colnames(DF3) <- c('Time', 'Generation', 'Population')
head(DF3)
In [155]:
# 시각화 -geom_area() 영역 그래프
G1 <- ggplot(DF3, aes(x=Time, y=Population, colour=Generation, fill=Generation)) +
geom_area(alpha=.6) + theme_wsj()
G1
In [157]:
# y축 값 변경 - scale_y_continuous(lables = comma)
G2 <- ggplot(DF3, aes(x=Time, y=Population, colour=Generation, fill=Generation)) +
geom_area(alpha=.6) + theme_wsj()
G2 + scale_y_continuous(labels = comma)
# label 인자를 사용해 y축 레이블을 천 단위마다 콤마로 표시
In [ ]:
'R' 카테고리의 다른 글
[R] D3js 와 js를 활용한 시각화 (0) | 2020.07.09 |
---|---|
[R] R 필수 패키지 설치 및 기초 (0) | 2020.07.08 |
[R] 데이터 시각화 (0) | 2020.07.08 |
[R] 기술통계 - 실전예제 (0) | 2020.07.08 |
[R] 기술통계 (0) | 2020.07.08 |
댓글