Ch1. R dplyr 활용
0. 데이터 불러오기
다운로드 링크 : https://www.kaggle.com/daiearth22/uniqlo-fastretailing-stock-price-prediction
xSTOCK = read.csv("C:/R/uniqlo-fastretailing-stock-price-prediction/Uniqlo(FastRetailing) 2012-2016 Training - stocks2012-2016.csv")
STOCK$Date = as.Date(STOCK$Date)
STOCK$Year = as.factor(format(STOCK$Date,"%Y"))
STOCK$Day = as.factor(format(STOCK$Date,"%a"))
str(STOCK)
xxxxxxxxxx
> str(STOCK)
'data.frame': 1226 obs. of 9 variables:
$ Date : Date, format: "2016-12-30" "2016-12-29" ...
$ Open : int 42120 43000 43940 43140 43310 43660 43900 42910 42790 43350 ...
$ High : int 42330 43220 43970 43700 43660 43840 44370 43630 43150 43550 ...
$ Low : int 41700 42540 43270 43140 43090 43190 43610 42860 42740 42810 ...
$ Close : int 41830 42660 43270 43620 43340 43480 44000 43620 43130 43130 ...
$ Volume : int 610000 448400 339900 400100 358200 381600 658900 499400 ...
$ Stock.Trading: num 2.56e+10 1.92e+10 1.48e+10 1.74e+10 1.55e+10 ...
$ Year : Factor w/ 5 levels "2012","2013",..: 5 5 5 5 5 5 5 5 5 5 ...
$ Day : Factor w/ 5 levels "금","목","수",..: 1 2 3 5 4 2 3 5 4 1 ...
1. 집계 데이터 만들기
원하는 그래프를 그리려고 하다 보면, 가끔 데이터의 집계된 결과를 통해 그래프를 작성해야 될 떄가 있습니다. dplyr을 활용하면 데이터 집계 과정과 시각화 과정을 함께 할 수 있습니다. 시각화를 다루기 전에, 자주 쓰이는 dplyr 명령어들을 다루도록 하겠습니다.
group_by
집계 기준 변수를 정해주는 명령어입니다.
summarise
집계 기준 변수 및 명령어에 따라 요약값을 계산합니다.
xxxxxxxxxx
Group_Data = STOCK %>%
group_by(Year,Day) %>%
summarise(Mean = round(mean(Open)),
Median = round(median(Open)),
Max = round(max(Open)),
Counts = length(Open))
xxxxxxxxxx
> head(Group_Data)
# A tibble: 6 x 6
# Groups: Year [2]
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2012 금 17179 17280 21480 50
2 2012 목 17161 17220 21300 51
3 2012 수 17125 17215 21040 52
4 2012 월 17099 17200 20320 45
5 2012 화 17099 17225 20610 50
6 2013 금 32641 33850 43950 51
ungroup
group으로 묶인 데이터를 그룹 해제 시켜주는 명령어입니다.
xxxxxxxxxx
Ungroup_Data = Group_Data %>%
ungroup()
xxxxxxxxxx
> head(Ungroup_Data)
# A tibble: 6 x 6
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2012 금 17179 17280 21480 50
2 2012 목 17161 17220 21300 51
3 2012 수 17125 17215 21040 52
4 2012 월 17099 17200 20320 45
5 2012 화 17099 17225 20610 50
6 2013 금 32641 33850 43950 51
ungroup을 해주는 이유
- group_by를 통해 발생할 수 있는 error 방지를 합니다.
xxxxxxxxxx
# 예시
Error in mutate_impl(.data, dots) :
Column `Class` can't be modified because it's a grouping variable
- group_by 여부에 따라 결과가 다르게 나옵니다.
count
집계 기준에 따라 데이터의 row 갯수를 계산해줍니다. summarise 내에서 쓰인 length와 비슷한 같은 기능을 수행합니다.
xxxxxxxxxx
Count_Data = STOCK %>%
group_by(Year,Day) %>%
count()
xxxxxxxxxx
> head(Count_Data)
# A tibble: 6 x 3
# Groups: Year, Day [6]
Year Day n
<fct> <fct> <int>
1 2012 금 50
2 2012 목 51
3 2012 수 52
4 2012 월 45
5 2012 화 50
6 2013 금 51
2. 데이터 Sampling
조건에 따라 데이터 추출하기
원하는 조건에 따라 데이터를 추출하는 명령어입니다. filter(), subset()을 활용하면 됩니다. 두 명령어 모두 같은 기능을 수행하니 편하신 명령어를 사용하면 됩니다.
xxxxxxxxxx
Subseted_Data = Group_Data %>%
filter(Year == "2012")
head(Subseted_Data)
xxxxxxxxxx
> head(Subseted_Data)
# A tibble: 5 x 6
# Groups: Year [1]
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2012 금 17179 17280 21480 50
2 2012 목 17161 17220 21300 51
3 2012 수 17125 17215 21040 52
4 2012 월 17099 17200 20320 45
5 2012 화 17099 17225 20610 50
데이터 중복 제거하기
데이터에 내에 존재하는 중복데이터를 제거합니다. 명령어는 distinct()를 사용합니다.
xxxxxxxxxx
# 중복 데이터 생성
SL = sample(1:nrow(Group_Data),500,replace = TRUE)
Duplicated_Data = Group_Data[SL,]
xxxxxxxxxx
> dim(Duplicated_Data)
[1] 500 6
Group_Data는 25개의 행(row)로 구성되어 있으나, 중복을 허용하여 500개로 증가시켜버리면 중복데이터가 무조건 발생하게 됩니다.
xxxxxxxxxx
Duplicated_Data2 = Duplicated_Data %>%
distinct(Year,Day,Mean,Median,Max,Counts)
xxxxxxxxxx
> dim(Duplicated_Data2)
[1] 25 6
중복 제거를 한 후, 데이터의 행(row)이 25로 돌아온 것을 확인할 수 있습니다.
샘플 데이터 무작위 추출
데이터의 행이 너무 많은 경우, 그래프를 그릴 때 연산속도가 오래 걸리며, R이 다운될 수 있는 문제가 있습니다. 그런 경우, 무작위로 샘플 데이터를 뽑아, 가볍게 시각화를 하는 것도 좋은 방법입니다. 명령어는 sample_frac(), sample_n()을 사용합니다. frac은 size에서 비율(0 ~ 1)을, n은 행의 갯수를 입력합니다.
group지정 여부에 따라 sample 결과가 다르게 나타납니다.
xxxxxxxxxx
# 그룹이 지정되어 있는 데이터
Sample_Frac_Gr = Group_Data %>%
sample_frac(size = 0.4, replace = FALSE)
Sample_Frac_Gr
xxxxxxxxxx
> Sample_Frac_Gr
# A tibble: 10 x 6
# Groups: Year [5]
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2012 목 17161 17220 21300 51
2 2012 수 17125 17215 21040 52
3 2013 목 32906 33700 44800 51
4 2013 금 32641 33850 43950 51
5 2014 월 36372 35300 45730 45
6 2014 금 36403 35615 45650 50
7 2015 월 48285 47432 60820 46
8 2015 목 48592 47715 60800 51
9 2016 금 34029 34310 43350 50
10 2016 월 34185 34710 43950 47
각 년도에서 2개씩 균형있게 sampling된 것을 확인할 수 있습니다.
xxxxxxxxxx
# ungroup으로 그룹지정을 해제한 데이터
Sample_Frac_Un = Ungroup_Data %>%
sample_frac(size = 0.4, replace = FALSE)
Sample_Frac_Un
xxxxxxxxxx
> Sample_Frac_Un
# A tibble: 10 x 6
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2014 목 36358 35865 45535 51
2 2012 금 17179 17280 21480 50
3 2016 목 34434 34740 43660 47
4 2015 화 48548 47410 60450 49
5 2014 수 36324 35785 45155 51
6 2013 금 32641 33850 43950 51
7 2015 금 48522 47205 61550 51
8 2015 수 48532 47550 59880 47
9 2014 화 36440 35985 44800 47
10 2012 수 17125 17215 21040 52
sample_n()
xxxxxxxxxx
Sample_N_Gr = Group_Data %>%
sample_n(size = 2, replace = FALSE)
Sample_N_Gr
xxxxxxxxxx
> Sample_N_Gr
# A tibble: 10 x 6
# Groups: Year [5]
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2012 화 17099 17225 20610 50
2 2012 금 17179 17280 21480 50
3 2013 월 32825 33525 43400 42
4 2013 수 32888 33850 42550 50
5 2014 금 36403 35615 45650 50
6 2014 월 36372 35300 45730 45
7 2015 수 48532 47550 59880 47
8 2015 월 48285 47432 60820 46
9 2016 수 34292 34245 43940 50
10 2016 목 34434 34740 43660 47
각 년도별 2개씩 뽑힌 것을 확인할 수 있습니다. group이 적용되어 있는 경우에는 현재 데이터에서는 size 값을 5보다 큰 숫자를 설정할 수가 없습니다. (각 년도별 5개씩 데이터가 있기 때문)
xxxxxxxxxx
Sample_N_Un = Ungroup_Data %>%
sample_n(size = 10, replace = FALSE)
Sample_N_Un
xxxxxxxxxx
> Sample_N_Un
# A tibble: 10 x 6
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2014 화 36440 35985 44800 47
2 2015 화 48548 47410 60450 49
3 2015 금 48522 47205 61550 51
4 2014 금 36403 35615 45650 50
5 2013 화 32631 33650 42800 51
6 2014 수 36324 35785 45155 51
7 2013 월 32825 33525 43400 42
8 2016 목 34434 34740 43660 47
9 2012 금 17179 17280 21480 50
10 2016 수 34292 34245 43940 50
무작위로 10개가 뽑힌 것을 확인할 수 있습니다.
정해진 Index에 따라 데이터 추출하기
무작위 추출이 아닌, 순서대로 뽑거나 원하는 구간만 설정해서 데이터를 뽑아내는 방법입니다. 명령어는 slice(), top_n()이 있습니다.
slice()는 Index를 직접 설정함으로, 원하는 구간만 추출할 수 있습니다. 이때 Dataset은 ungroup()이 되어 있는 데이터로 진행해야 됩니다.
xxxxxxxxxx
Slice_Data = Ungroup_Data %>%
slice(1:10)
Slice_Data
xxxxxxxxxx
> Slice_Data
# A tibble: 10 x 6
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2012 금 17179 17280 21480 50
2 2012 목 17161 17220 21300 51
3 2012 수 17125 17215 21040 52
4 2012 월 17099 17200 20320 45
5 2012 화 17099 17225 20610 50
6 2013 금 32641 33850 43950 51
7 2013 목 32906 33700 44800 51
8 2013 수 32888 33850 42550 50
9 2013 월 32825 33525 43400 42
10 2013 화 32631 33650 42800 51
top_n()은 설정해준 변수를 기준으로 가장 값이 높은 n개의 데이터를 가져옵니다.
xxxxxxxxxx
Top_n_Data = Ungroup_Data %>%
top_n(5,Mean) # Mean이 가장 높은 5개 데이터 추출
Top_n_Data
xxxxxxxxxx
> Top_n_Data
# A tibble: 5 x 6
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2015 금 48522 47205 61550 51
2 2015 목 48592 47715 60800 51
3 2015 수 48532 47550 59880 47
4 2015 월 48285 47432 60820 46
5 2015 화 48548 47410 60450 49
데이터 정렬하기
데이터를 특정 변수를 기준으로 정렬하는 방법입니다. arrange()를 이용합니다. 마찬가지로 ungroup()이 설정된 데이터로 정렬합니다. 만약 group_by()가 설정되어 있는 데이터를 기준으로 정렬 할 경우, Year별로 정렬합니다.
오름차순
xxxxxxxxxx
# ungroup으로 그룹지정을 해제한 데이터
Asce_Data = Ungroup_Data %>%
arrange(Mean) # Mean을 기준으로 오름차순 정렬
head(Asce_Data)
xxxxxxxxxx
> head(Asce_Data)
# A tibble: 6 x 6
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2012 월 17099 17200 20320 45
2 2012 화 17099 17225 20610 50
3 2012 수 17125 17215 21040 52
4 2012 목 17161 17220 21300 51
5 2012 금 17179 17280 21480 50
6 2013 화 32631 33650 42800 51
내림차순
내림차순은 변수에 '-'를 붙여주면 됩니다.
xxxxxxxxxx
Desc_Data = Ungroup_Data %>%
arrange(-Mean)
head(Desc_Data)
xxxxxxxxxx
> head(Desc_Data)
# A tibble: 6 x 6
Year Day Mean Median Max Counts
<fct> <fct> <dbl> <dbl> <dbl> <int>
1 2015 목 48592 47715 60800 51
2 2015 화 48548 47410 60450 49
3 2015 수 48532 47550 59880 47
4 2015 금 48522 47205 61550 51
5 2015 월 48285 47432 60820 46
6 2014 화 36440 35985 44800 47
원하는 변수(Colomn)만 뽑아내기
데이터를 핸들링 할 때, 모든 변수들을 가져갈 필요는 없습니다. 이런 경우 select(), select_if()를 활용하여 원하는 변수들을 뽑아낼 수 있습니다.
select()를 통해 원하는 변수를 뽑아낼 수 있습니다. 인덱스를 통해 뽑아도 되고, 변수명을 입력해서 뽑아내도 됩니다. 편하신 방법대로 하시면 됩니다.
xxxxxxxxxx
# Index 활용
Select_Data = Group_Data %>%
select(1:2)
# Column명 활용
Select_Data = Group_Data %>%
select(Year,Day)
head(Select_Data)
xxxxxxxxxx
> head(Select_Data)
# A tibble: 6 x 2
# Groups: Year [2]
Year Day
<fct> <fct>
1 2012 금
2 2012 목
3 2012 수
4 2012 월
5 2012 화
6 2013 금
select_if()를 통해 뽑는 조건을 줄 수 있습니다. 예를 들어, 데이터 타입에 따라 뽑아낼 수 있습니다.
xxxxxxxxxx
# Factor 변수만 뽑기
Select_if_Data1 = Group_Data %>%
select_if(is.factor)
head(Select_if_Data1)
xxxxxxxxxx
> head(Select_if_Data1)
# A tibble: 6 x 2
# Groups: Year [2]
Year Day
<fct> <fct>
1 2012 금
2 2012 목
3 2012 수
4 2012 월
5 2012 화
6 2013 금
데이터 타입이 Factor인 변수만 뽑아서 데이터 셋을 만든 것을 확인할 수 있습니다.
xxxxxxxxxx
# integer 변수만 뽑기
Select_if_Data2 = Group_Data %>%
select_if(is.integer)
새로운 변수 만들기 혹은 한번에 처리하기
데이터 핸들링 과정에서 새로운 변수(Column)를 만들고자 할 때 필요한 기능입니다. 대표적으로는 mutate(), mutate_if(), mutate_at()이 있습니다.
mutate()는 하나의 변수를 명령어에 따라 추가하는 방법입니다.
xxxxxxxxxx
Mutate_Data = STOCK %>%
mutate(Divided = round(High/Low,2)) %>%
select(Date,High,Low,Divided)
head(Mutate_Data)
xxxxxxxxxx
> head(Mutate_Data)
Date High Low Divided
1 2016-12-30 42330 41700 1.02
2 2016-12-29 43220 42540 1.02
3 2016-12-28 43970 43270 1.02
4 2016-12-27 43700 43140 1.01
5 2016-12-26 43660 43090 1.01
6 2016-12-22 43840 43190 1.02
mutate_if()은 지정해준 모든 변수에 대해 계산식을 적용시켜 줍니다. 예를 들어, 데이터의 타입을 변경하고 싶을 때, as.factor()같은 명령어를 하나씩 적용시키는 방법은 시간을 많이 잡아먹는 노가다 작업입니다. 이런 경우, mutate_if()를 통해 한번에 데이터 타입을 변경시켜줄 수 있습니다.
xxxxxxxxxx
# integer 타입 변수를 모두 numeric으로 변경
Mutate_If_Data = STOCK %>%
mutate_if(is.integer,as.numeric)
str(Mutate_If_Data)
xxxxxxxxxx
> str(Mutate_If_Data)
'data.frame': 1226 obs. of 9 variables:
$ Date : Date, format: "2016-12-30" "2016-12-29" ...
$ Open : num 42120 43000 43940 43140 43310 ...
$ High : num 42330 43220 43970 43700 43660 ...
$ Low : num 41700 42540 43270 43140 43090 ...
$ Close : num 41830 42660 43270 43620 43340 ...
$ Volume : num 610000 448400 339900 400100 358200 ...
$ Stock.Trading: num 2.56e+10 1.92e+10 1.48e+10 1.74e+10 1.55e+10 ...
$ Year : Factor w/ 5 levels "2012","2013",..: 5 5 5 5 5 5 5 5 5 5 ...
$ Day : Factor w/ 5 levels "금","목","수",..: 1 2 3 5 4 2 3 5 4 1 ...
mutate_at()은 지정한 변수들에 대해 계산식을 적용시키는 명령어입니다.
xxxxxxxxxx
Mutate_At_Data = STOCK %>%
mutate_at(vars(-Date,-Year,-Day),log) %>%
select_if(is.numeric)
head(Mutate_At_Data)
xxxxxxxxxx
> head(Mutate_At_Data)
Open High Low Close Volume Stock.Trading
1 10.64828 10.65325 10.63826 10.64137 13.32121 23.96695
2 10.66896 10.67406 10.65820 10.66102 13.01344 23.67756
3 10.69058 10.69126 10.67521 10.67521 12.73641 23.41659
4 10.67221 10.68510 10.67221 10.68327 12.89947 23.58134
5 10.67614 10.68419 10.67105 10.67683 12.78885 23.46719
6 10.68419 10.68830 10.67336 10.68006 12.85213 23.53185
Date, Year, Day 변수를 제외하고 나머지 변수들은 모두 log 변환이 적용된 것을 확인할 수 있습니다.
여기까지 dplyr의 활용법을 다루었습니다. 모든 기능을 다룬 것은 아니고, 제 경험상 많이 썼던 기능들을 위주로 선별하였습니다. dplyr로 핸들링 한 후, %>%를 이용하여 바로 ggplot() 명령어와 연계할 수 있기 때문에 매우 효율적으로 작업을 할 수 있습니다.
댓글
댓글 쓰기