<aside> 💡 [2강 주요 함수]
</aside>
데이터 분석의 첫 번째 태스크는 데이터를 그래프로 나타내는 것이다. 그래프는 패턴, 특이한 관측값, 시간에 따른 변화, 변수 간 관계 등 데이터의 많은 특징들이 시각화될 수 있게 한다. 플롯에서 볼 수 있는 특징들은, 사용할 예측 방식에 가능한 한 많이 포함되어야 한다. 데이터 종류가 사용할 예측 방식을 결정하는 것 만큼이나, 데이터 종류는 또한 어떤 그래프가 적절한지도 결정한다. 우선 R에서 그려보자!
‘시계열’은 측정치의 목록과, 해당 값들이 어느 시간대에 측정되었는지에 대한 정보(index)로 이루어져 있다. R에서 tsibble object로 저장된다.
index variable
지난 몇년 간의 연간 관측치가 있다고 가정해보자. 이걸 tsibble 함수를 활용해 tsibble 객체로 바꿀 것이다.
y <- tsibble(
year = 2015:2019,
observation = c(123,39,78,52,110),
index=year
)
tsibble 객체는 시계열적 구조를 도입함으로써 tibble 객체를 확장시킨다.위 예시에서는 Year 열을 본 시계열의 index로 설정하며, 관측치인 Observation을 관측 주기인 Year과 관련지었다.
‘매년’보다 주기가 짧은 관측치의 경우, 우리는 index에 time class 함수를 적용해야 한다. 월 주기의 데이터셋 ‘z’가 있다고 생각해보자. 이 tibble 객체는 하단의 코드를 통해 tsibble 객체로 전환될 수 있다.
z <- tibble(
month = c('2019 Jan', '2019 Feb', '2019 Mar', '2019 Apr', '2019 May'),
observation = c(50,23,34,30,25)
)
#index가 시간 간격의 단위 뜻함!
z %>% mutate(month = yearmonth(month)) %>%
as_tsibble(index = month) %>% View()
먼저, month 열이 문자에서 월 주기 시간 객체로 yearmonth 함수로 인해 바뀌었다. 그리고나서, index를 month로 지정한 후 as_tsibble 함수를 활용해 데이터프레임을 tsibble 로 변환했다. [1M] 표기가 추가된 것을 알 수 있을 것이다.
⇒ yearquarter ~ yearweek 함수는 tsibble 패키지에 있는!
The key variables
tsibble은 또한 한 객체 안에 여러 시계열을 포함할 수 있다. 예컨대 남자와 여자의 올림픽 100m, 10000m 기록을 포함한 데이터셋이 있다고 가정하자.
olympic_running
#> # A tsibble: 312 x 4 [4Y]
#> # Key: Length, Sex [14]
#> Year Length Sex Time
#> <int> <int> <chr> <dbl>
#> 1 1896 100 men 12
#> 2 1900 100 men 11
#> 3 1904 100 men 11
#> 4 1908 100 men 10.8
#> 5 1912 100 men 10.8
#> 6 1916 100 men NA
#> 7 1920 100 men 10.8
#> 8 1924 100 men 10.6
#> 9 1928 100 men 10.8
#> 10 1932 100 men 10.3
#> # ℹ 302 more rows
tsibble 객체임을 알 수 있고, 312개의 행과 4개의 열이 있다. [4Y]는 본 데이터의 주기가 4년임을 알려준다. 이러한 정보 아래에는 key 변수에 대한 정보 있는데, key로 설정한 변수의 데이터에 14개의 분리된 시계열(결측치)이 있음을 알려준다. 1916년에는 1차 세계 대전으로 인해 올림픽이 열리지 않았다. 이 14개의 시계열은 각 변수(DF의 열)마다 분리해서 세어진다.
distinct 함수는 관측치의 unique 값을 보여준다. 변수 2개 이상 넣어도 따로따로 고유값 보여준다. (선택한 variable의 관측치가 모두 중복되는 게 아니면 unique 값이 아니라 전부 보여줌)
olympic_running |> distinct(Sex)
#> # A tibble: 2 × 1
#> Sex
#> <chr>
#> 1 men
#> 2 women
z |> mutate(month = yearmonth(month)) %>%
as_tsibble(index = month) %>% distinct(observation, ob2)
# A tibble: 5 x 2
observation ob2
<dbl> <dbl>
1 50 10
2 23 30
3 34 50
4 30 80
5 25 90
(값 중복 예시)
# A tibble: 5 x 2
observation ob2
<dbl> <dbl>
1 50 90
2 34 90
3 34 50
4 50 50
5 25 90
tsibble 과 놀아보자
tsibble 객체에는 mutate, filter, select, summarize 등 여러 dplyr 함수를 사용할 수 있다. 호주의 의약품 판매 데이터를 포함하는 PBS tsibble을 활용해 설명해보겠다.
PBS
#> # A tsibble: 67,596 x 9 [1M]
#> # Key: Concession, Type, ATC1, ATC2 [336]
#> Month Concession Type ATC1 ATC1_desc ATC2 ATC2_desc Scripts Cost
#> <mth> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
#> 1 1991 Jul Concessional Co-pay… A Alimenta… A01 STOMATOL… 18228 67877
#> 2 1991 Aug Concessional Co-pay… A Alimenta… A01 STOMATOL… 15327 57011
#> 3 1991 Sep Concessional Co-pay… A Alimenta… A01 STOMATOL… 14775 55020
#> 4 1991 Oct Concessional Co-pay… A Alimenta… A01 STOMATOL… 15380 57222
#> 5 1991 Nov Concessional Co-pay… A Alimenta… A01 STOMATOL… 14371 52120
#> 6 1991 Dec Concessional Co-pay… A Alimenta… A01 STOMATOL… 15028 54299
#> 7 1992 Jan Concessional Co-pay… A Alimenta… A01 STOMATOL… 11040 39753
#> 8 1992 Feb Concessional Co-pay… A Alimenta… A01 STOMATOL… 15165 54405
#> 9 1992 Mar Concessional Co-pay… A Alimenta… A01 STOMATOL… 16898 61108
#> 10 1992 Apr Concessional Co-pay… A Alimenta… A01 STOMATOL… 18141 65356
#> # ℹ 67,586 more rows
이 데이터는 1991년 7월부터 2008년 6월까지 호주의 월간 의약품 처방 데이터를 포함한다. 다양한 할인 종류와 의약품 분류코드(Anatomical Therapeutic Chemical, ATC)에 따라 분류돼 있다. 우리는 처방된 총 비용(AUD 기준) 보려 한다.
(1) A10 처방을 골라내고자 filter 함수를 사용한다. (행 선택)
(2) 분석에서 필요한 변수들만 select 함수로 골라낸다. (열 선택)
(3) (별 말 없으면) 시간 인덱스 기준으로 summarize 함수 적용해 기초 통계를 낸다.
(4) mutate 함수로 새 변수를 만든다.
(5) 새 tsibble로 저장한다.
PBS |>
filter(ATC2 == "A10") |>
select(Month, Concession, Type, Cost) |>
summarise(TotalC = sum(Cost)) |>
mutate(Cost = TotalC / 1e6) -> a10
The seasonal period
시계열의 주기(seasonal period)는 다음 패턴이 반복되기까지 관측치의 개수를 의미한다. 대체로 시간 인덱스 변수에 의해 자동으로 파악된다.
분기, 월, 주간 데이터에는 하나의 주기만 있다. (이때, 윤년을 고려하면 평균적으로 1년에는 52.18주가 있다.) 대체로 시계열 모델에서는 정수의 주기만 다룰 수 있기 때문에, 주기를 정수로 근사하는 게 유용하다.
데이터가 주 1회보다 더 많이 측정됐다면, 보통 둘 이상의 패턴이 있다. 예컨대 매일 측정된 데이터는 주간, 연간 주기가 있을 수 있다. 비슷하게, 분 단위로 측정된 데이터에는 시간, 일간, 주간, 연간 주기가 있을 수 있다. 더 복잡하거나 불규칙적인 주기는 lubridate 패키지의 period 함수로 지정할 수 있다.
EX)
period(c(3, 1, 2, 13, 1), c("second", "minute", "hour", "day", "week"))
시계열 데이터의 경우, 가장 먼저 그려야 할 것은 시간 그래프이다. 즉, 연속적인 관측치들은 직선으로 연결되어 관측시간에 대해 그려진다.
melsyd_economy <- ansett |>
filter(Airports == "MEL-SYD", Class == "Economy") |>
mutate(Passengers = Passengers/1000)
autoplot(melsyd_economy, Passengers) +
labs(title = "Ansett airlines economy class",
subtitle = "Melbourne-Sydney",
y = "Passengers ('000)")
autoplot 함수를 자주 쓰게 될 것이다. 첫 매개변수로 뭘 넣든 적절한 그래프를 내놓을 것이다. 이 경우, melsyd_economy를 시계열 데이터로 인식하고 시간 그래프를 그려졌다.
이 시간 그래프는 즉시 흥미로운 특징들을 밝혀낸다.
<aside> 💡 - 노동 쟁의로 인해 1989년에 손님이 없었던 때가 있다.
</aside>