오늘은 저번 포스팅에 이어서 T아카데미 데이터 시각화 with R 복습을 해보겠다
강의 링크는 아래를 참조!
tacademy.skplanet.com/live/player/onlineLectureDetail.action?seq=172
데이터 시각화 with R | T아카데미 온라인강의
1. R 시각화 라이브러리인 ggplot2의 기본적인 사용방법에 대해 알아봅니다. 2. ggplot2를 활용하여 기본 그래프 및 차트, 비정형 그래프 그리기 등 표현방법에 대해 ..
tacademy.skplanet.com
롤리팝차트
데이터 불러오기
read.csv("kovo.csv") %>% as_tibble() -> kovo # 남녀부 배구데이터
남녀 구분하여 구단별 퀵오픈에 대한 롤리팝 차트 그리기
kovo %>% ggplot(aes(x=reorder(구단,퀵오픈), y=퀵오픈, color=남녀부))+ # reorder 기본값은 오름차순, 내림차순: -퀵오픈
geom_segment(aes(xend=구단,yend=0))+
geom_point(size=5)+
coord_flip()+
facet_grid(남녀부~.,scales="free_y")
# facet_grid, facet_wrap 차이
# facet_grid, ~변수,변수~. 에따라 x,y축 순서 변경
# facet_wrap은 그렇지 않음, 대신 ncol, nrow등 행렬로 ,변수 2개 사용 가능
geom_segment는 aes(x,y,xend,yend) : (x,y),(xend,yend)를 직선으로 연결함, 롤리팝 차트 위해 필수!!
지금 퀵오픈 값에 선을 그어야 하므로 x=구단,y=퀵오픈 -> xend=구단,yend=0
scales="free_y" , facet_grid로 칸 나눠지면서 생기는 빈칸 없애줌
theme 함수를 통해 다듬기
kovo %>% ggplot(aes(x=reorder(구단,퀵오픈), y=퀵오픈, color=남녀부))+
geom_segment(aes(xend=구단,yend=0))+
geom_point(size=5)+
coord_flip()+
facet_grid(남녀부~.,scales="free_y")+
labs(x="")+
scale_color_manual(values = c("#2D2C76","#D12C76"))+ # 남녀 색깔 지정
theme(axis.ticks =element_blank(), # 눈금 없애기
panel.grid = element_blank(), # 배경 그리드 없애기
panel.background = element_rect("#F6F6F6"), # 배경색 변경
strip.background = element_rect("#989797")) # 남녀 써있는 상단바
여기까지가 수업 내용이었지만, 추가적으로 중간값을 넣어주면 남녀를 더 구분하기 쉬울것이라고 생각했다
남녀 퀵오픈 중간값 표시
kovo %>% mutate(med_line = ifelse(남녀부 == "남",812,971)) -> kovo2
kovo2 %>% ggplot(aes(x=reorder(구단,퀵오픈), y=퀵오픈, color=남녀부))+
geom_segment(aes(xend=구단,yend=0))+
geom_point(size=5)+
coord_flip()+
facet_grid(남녀부~.,scales="free_y")+
labs(x="")+
scale_color_manual(values = c("#2D2C76","#D12C76"))+
theme(axis.ticks =element_blank(),
panel.grid = element_blank(),
panel.background = element_rect("#F6F6F6"),
strip.background = element_rect("#989797"))+
geom_hline(aes(yintercept=med_line),color="#989797")
중간값을 달기 위해서 med_line이라는 새로운 변수를 생성했다.
변수를 새로 생성하면 쉽게 facet_grid로 나누어진 자료에도 각각 라인을 그릴 수 있다.
그 후 geom_hline 함수를 통해 중간값 선을 넣어 주었다.
이제 저 회색선이 중간값이다! 라고 라벨을 달아줘야하는데 문제는 남녀를 구분해야한다는 것,,
남녀 퀵오픈 중간값 라벨 표시하기
text_df = data.frame(label = c("남자 퀵오픈 중간값", "여자 퀵오픈 중간값"),
x = c(1,1),
y = c(812,971),
남녀부 = c("남","여")) # 이거 중요!! 없으면 에러
kovo2 %>% ggplot(aes(x=reorder(구단,퀵오픈), y=퀵오픈, color=남녀부))+
geom_segment(aes(xend=구단,yend=0))+
geom_point(size=5)+
coord_flip()+
facet_grid(남녀부~.,scales="free_y")+
labs(x="")+
scale_color_manual(values = c("#2D2C76","#D12C76"))+
theme(axis.ticks =element_blank(),
panel.grid = element_blank(),
panel.background = element_rect("#F6F6F6"),
strip.background = element_rect("#989797"))+
geom_hline(aes(yintercept=med_line),color="#989797")+
geom_text(data = text_df, mapping = aes(label=label,x=x,y=y),size=2.5) # 주석
중간값 라인을 그려주기 위해서 새로운 변수를 만들었다면, 이번에는 라벨링을 위한 데이터프레임을 만들었다.
여기서 x, y는 라벨이 놓여줄 위치를 의미한다.
남녀부를 추가한 이유는 새 데이터가 남녀로 구분되어있어야만 라벨링도 구분되어서 따로 나올 수 있다!!!! 매우 중요
그 후, geom_text에서 mapping을 통해 라벨링을 했다.
y축 범위 바꾸고 퀵오픈값 라벨링
kovo2 %>% ggplot(aes(x=reorder(구단,퀵오픈), y=퀵오픈, color=남녀부))+
ylim(300,1200)+
geom_segment(aes(xend=구단,yend=300))+
geom_point(size=8)+ # 크기 키움
coord_flip()+
facet_grid(남녀부~.,scales="free_y")+
labs(x="", y="", title = "배구 퀵오픈")+ # y축 없애기, 제목 생성
scale_color_manual(values = c("#2D2C76","#D12C76"))+
theme(axis.ticks =element_blank(),
panel.grid = element_blank(),
panel.background = element_rect("#F6F6F6"),
strip.background = element_rect("#989797"),
axis.text.x = element_blank(), # 숫자 없애기
plot.title = element_text(hjust = 0.5))+ # 제목 가운데에 위치
geom_hline(aes(yintercept=med_line),color="#989797")+
geom_text(aes(label=퀵오픈),col="white",size=3)+ # 퀵오픈 추가
geom_text(data = text_df, mapping = aes(label=label,x=x,y=y),size=2.5) # 주석
차이를 좀 더 극명하게 보여주기 위해 y축을 300부터 시작하도록 했다. 이때 주의할 점은 geom_segment의 yend=300으로 변경해줘야 한다는 점!
또한, 밑의 퀵오픈 축을 삭제하고 퀵오픈값을 라벨링 했다. 디자인적으로 훨씬 더 깔끔해진 것을 확인할 수 있다.
다만 아쉬운점은 구단별 간격이 좁다는 것인데 늘리는 방법을 모르겠다..축 길이를 늘리는 방법 아시는 분 있으면 댓글로 남겨주세요..
덤벨차트
다음으로는 덤벨차트! 두 변수를 비교하는 시각화를 할 때 유용하다
데이터 불러오기
read.csv("fifa.csv") %>% as_tibble() -> fifa # 1993~2018 피파 데이터
아시안컵에서 국가별 최고랭킹과 최저랭킹을 시각화 해보자
국가별 최고 랭킹 점으로 표시
fifa %>%
filter(confederation == "AFC") %>% # AFC: 아시안컵
group_by(country_full) %>%
summarise(최고=min(rank), 최저=max(rank)) %>%
ggplot(aes(x=최고, y=reorder(country_full, -최고)))+ # 등수 높은 국가가 맨 위에
geom_point()+
scale_x_reverse() # 랭킹은 작을수록 좋으므로
여기서 주의할 점은 랭킹 순위는 작을수록 높다! 라는 사실을 간과해선 안된다.
그래서 국가명을 정렬할때도 "-최고" 변수앞에 -를 붙여주었다.
또한 scale_x_reverse() 함수를 통해 x축도 뒤집어주었다 (큰->작)
국가별 최저 랭킹 점으로 표시
fifa %>%
filter(confederation == "AFC") %>%
group_by(country_full) %>%
summarise(최고=min(rank), 최저=max(rank)) %>%
ggplot(aes(x=최고, y=reorder(country_full, -최고)))+
geom_point(col="red")+
scale_x_reverse()+
geom_point(aes(x=최저),col="blue")
또다시 geom_point를 이용해 이번에는 최저 순위까지 찍어주었다
최고순위, 최저순위 이어주기
fifa %>%
filter(confederation == "AFC") %>%
group_by(country_full) %>%
summarise(최고=min(rank), 최저=max(rank)) %>%
ggplot(aes(x=최고, y=reorder(country_full, -최고)))+
geom_point(col="red")+
scale_x_reverse()+
geom_point(aes(x=최저),col="blue")+
geom_segment(aes(yend=reorder(country_full, -최고),xend=최저-1.5,x=최고+1.5),col="grey")+ # 선위치 조절
labs(title="피파 아시안컵 최저순위 최고순위",y="",x="순위")+
theme(axis.ticks =element_blank(),
panel.grid = element_blank(),
panel.background = element_rect("white"),
plot.title = element_text(hjust = 0.5))
역시나 롤리팝 차트처럼 geom_segment를 이용해서 최저 순위와 최고 순위를 연결해주었다
이때 geom_segment에서 xend=최저-1.5, x=최고+1.5 로 한 이유는 이렇게 하지 않으면 선의 길이가 너무 길어져서 점과 겹치기 때문이다.
이렇게 덤벨차트도 끝! 최저 순위와 최고 순위를 한눈에 비교할 수 있게 되었다.
슬로프 차트
덤벨차트는 순위만을 비교했다면, 슬로프 차트는 다양한 속성의 증감을 비교할 때 더 효과적이다
데이터 불러오기
read.csv("kal.csv") %>% as_tibble() -> kal # 두 선수 데이터
두 배구 선수에 관한 데이터이다. 얼핏 보면 전혀 문제가 없어보이지만 이는 wide form 데이터이므로
long form 으로 바꿔줘야 컴퓨터가 그래프를 그리기 훨씬 수월하다.
tidy data로 형태 변경하기
kal %>% gather(-세터, key="공격", value="점유율")
wide form을 long form으로 변경시켜주는 함수는 gather! (반대는 spread)
gather(data, key,value)
key: column 이름에 나타난 값을 위한 변수명
value: column에서 가지고 있는 값을 저장하기 위한 변수명
data 부분에서 -세터는 세터를 제외한 나머지 변수 모두를 gather하라는 의미
두 선수의 공격 점유율 슬로프 차트로 표현하기
kal %>% gather(-세터, key="공격", value="점유율") %>%
ggplot(aes(x=세터, y=점유율,group=공격))+ # group=공격 없으면 세터기준으로 세로 직선 그어짐
geom_point()+
geom_line()+
geom_text(aes(label=paste(공격,format(점유율,digits=1))))
# label=paste(변수1,변수2...) : 여러개 변수 라벨링 하고싶을때
슬로프 차트의 핵심은 group과 geom_line()
group = 공격 옵션이 있어야 geom_line()에서 공격별로 라인을 그어준다
하지만 지금은 라벨이 너무 지저분하다. 공격명은 굳이 2번 써줄 필요가 없으므로 다음단계에서 지워주자!
공격명 라벨링 한 번만 쓰기 , 공격별 색깔 다르게 표시
kal %>% gather(-세터, key="공격", value="점유율") %>%
ggplot(aes(x=세터, y=점유율,group=공격,color=공격))+ # group=공격 없으면 세터기준으로 세로 직선 그어짐
geom_point()+
geom_line()+
geom_text(data=.%>%filter(세터=="유광우"),
aes(label=paste(공격, format(점유율, digits=1))), hjust=1.1)+
geom_text(data=.%>% filter(세터=="한선수"),
aes(label=format(점유율,digits=1)),hjust=-0.2)+
labs(title = "세터선수 공격 점유율 비교")+
theme(legend.position = "none",
axis.ticks=element_blank(),
panel.grid=element_blank(),
panel.background = element_blank(),
axis.text.y=element_blank(),
axis.title.y = element_blank(),
axis.title.x=element_blank(),
plot.title = element_text(hjust=0.5))
geom_text(data=.%>%filter(세터=="유광우"),
aes(label=paste(공격, format(점유율, digits=1))), hjust=1.1)
여기서 data=. 은 위 코드 데이터를 이어 받겠다라는 의미
훨씬 깔끔하고 가독성 좋은 슬로프 차트 완성!
이렇게 두번째 복습까지 포스팅 끝
하지만 아직 갈길이 멀다..
다음에는 네트워크 시각화와 가능하다면 레이스 차트까지 복습하기로!!
'Data' 카테고리의 다른 글
[python] 네이버 뉴스 기사 작성일, 제목, url 크롤링 ( BeautifulSoup ) (378) | 2021.02.16 |
---|---|
[python] SVM, PCA kaggle 필사 (유방암 데이터) (691) | 2021.02.05 |
[R] 데이터 시각화 with R ( 막대그래프/와플차트 ) (384) | 2021.01.26 |
[R] R로 하는 텍스트 전처리2 ( 동시 출현 빈도 / tf-idf/ wordcloud2) (feat. 기리보이) (372) | 2021.01.15 |
[R] R로 하는 텍스트 전처리( tidytext / KoNLP / wordcloud2 ) (378) | 2021.01.12 |