본문 바로가기
  • plotly로 바로쓰는 동적시각화 in R & 파이썬
실전에서 바로 쓰는 시계열 데이터 처리와 분석 in R/못다한 이야기

시계열 데이터의 결측치(Missing value) 처리 in R - part 3

by 아참형인간 2022. 9. 11.
tsibble.knit

이번 포스트에서는 시계열 데이터의 결측치 처리 방법 중 tsibble 클래스에 따라 살펴보도록 하겠다.

tsibble

tsibble 클래스는 tidyverse 생태계에서 사용되는 대표적인 데이터 클래스인 tibble 클래스를 시계열 데이터에 맞게 확장한 데이터 클래스이다. 이 tsibble 클래스의 시계열 데이터는 tsibble 패키지에서 제공하는 함수를 사용하여 결측치를 처리할 수 있다.

if (!require(tsibble)) {
  install.packages('tsibble')
  library(tsibble)
}

데이터 Import

사용하는 데이터는 Part 1에서 사용한 ‘tsAirgap’ 데이터를 tsibble 클래스 변환하여 사용하도록 하겠다. 다만 앞선 ts, xts, zoo와는 달리 tsibble은 NA로 설정된 데이터는 결측치로 판단하지 않는다. tsibble에서 결측치로 보는 데이터는 특정 시간의 데이터가 누락된 데이터이고 NA로 기록된 데이터는 결측치가 아닌 NA로 기록된 데이터로 판단한다.

따라서 tsAirgap 데이터에서 NA로 기록된 데이터를 다음과 같이 제거하여 사용한다.

tsAirgap.tsibble <- as_tsibble(tsAirgap) |>
  filter(!is.na(value))

tsAirgap.tsibble |> fabletools::autoplot()

tsibble 패키지에서는 결측치가 있는지를 점검하고, 어디에 결측치가 있는지, 결측치가 몇개인지를 확인하고 결측치를 메우는 함수를 제공한다.

has_gaps()

has_gaps()tsibble 클래스 데이터에 결측치가 있는지를 확인하는 함수이다. 이 함수에는 ‘.full’ 매개변수가 사용되는데 하나의 tsibble 객체안에 2개 이상의 시계열 데이터(열)이 있고 각각의 시간 범위가 다른 경우 다음과 같은 의미가 있다.

  • FALSE : 각각의 시계열 시간 범위내에서만 결측치를 확인
  • TRUE : tsibble 객체에 포함된 전체 시계열 데이터의 시간 범위에 대한 결측치를 확인
  • start() : 결측치 확인을 위한 시간 범위의 시작점을 설정
  • end() : 결측치 확인을 위한 시간 범위 끝점을 설정

tsAirgap과 같이 하나의 시계열 데이터(열)을 가지는 경우 ’.full’은 의미가 없다.

has_gaps(tsAirgap.tsibble, .full = FALSE)
## # A tibble: 1 x 1
##   .gaps
##   <lgl>
## 1 TRUE

scan_gaps()

has_gaps()를 사용해 결측치를 확인하였다면 이 결측치가 어디에 있는지 확인할 때 사용하는 함수가 scan_gaps()이다.

scan_gaps(tsAirgap.tsibble, .full = FALSE)
## # A tsibble: 13 x 1 [1M]
##      index
##      <mth>
##  1  1949 5
##  2  1949 9
##  3  1950 9
##  4 1950 11
##  5  1954 6
##  6  1956 3
##  7  1956 4
##  8  1956 5
##  9  1957 6
## 10 1957 11
## 11  1958 3
## 12 1959 12
## 13  1960 5

위의 결과에서 보면 전체 시계열에서 결측치가 있는 시간이 표시된다.

count_gaps()

count_gaps()는 시간 간격에 따른 결측치의 개수를 확인하는 함수이다. count_gaps()의 결과는 ’from’과 ’to’로 설정된 시간 간격의 결측치 개수를 계산해서 보여준다.

count_gaps(tsAirgap.tsibble, .full = TRUE)
## # A tibble: 11 x 3
##      .from     .to    .n
##      <mth>   <mth> <int>
##  1  1949 5  1949 5     1
##  2  1949 9  1949 9     1
##  3  1950 9  1950 9     1
##  4 1950 11 1950 11     1
##  5  1954 6  1954 6     1
##  6  1956 3  1956 5     3
##  7  1957 6  1957 6     1
##  8 1957 11 1957 11     1
##  9  1958 3  1958 3     1
## 10 1959 12 1959 12     1
## 11  1960 5  1960 5     1

위의 결과에서 보면 1956.3월부터 1956.5월까지 3개월간 결측치가 발생했다는 것이 보인다.

fill_gaps()

fill_gaps()는 결측치를 특정한 값으로 채우는 함수이다. 앞서 설명했던 ‘.full’ 매개변수를 사용하여 각각의 변수들의 결측치를 채우는 시간 범위를 설정할 수 있다. 다만 fill_gaps()는 앞선 세 함수와는 달리 결측치를 채울 값을 설정하는 매개변수를 추가한다. 이 매개변수가 비어있다면 NA로 채워지고 특정 값을 넣을 수도 있고 함수를 통해 채워질 값을 설정할 있다.

fill_gaps(tsAirgap.tsibble, .full = TRUE)
## # A tsibble: 144 x 2 [1M]
##      index value
##      <mth> <dbl>
##  1  1949 1   112
##  2  1949 2   118
##  3  1949 3   132
##  4  1949 4   129
##  5  1949 5    NA
##  6  1949 6   135
##  7  1949 7   148
##  8  1949 8   148
##  9  1949 9    NA
## 10 1949 10   119
## # ... with 134 more rows
fill_gaps(tsAirgap.tsibble, .full = TRUE) |> fabletools::autoplot()

fill_gaps(tsAirgap.tsibble, value = 1000, .full = TRUE)
## # A tsibble: 144 x 2 [1M]
##      index value
##      <mth> <dbl>
##  1  1949 1   112
##  2  1949 2   118
##  3  1949 3   132
##  4  1949 4   129
##  5  1949 5  1000
##  6  1949 6   135
##  7  1949 7   148
##  8  1949 8   148
##  9  1949 9  1000
## 10 1949 10   119
## # ... with 134 more rows
fill_gaps(tsAirgap.tsibble, value = 1000, .full = TRUE) |> fabletools::autoplot()

fill_gaps(tsAirgap.tsibble, value = median(value), .full = TRUE)
## # A tsibble: 144 x 2 [1M]
##      index value
##      <mth> <dbl>
##  1  1949 1   112
##  2  1949 2   118
##  3  1949 3   132
##  4  1949 4   129
##  5  1949 5   259
##  6  1949 6   135
##  7  1949 7   148
##  8  1949 8   148
##  9  1949 9   259
## 10 1949 10   119
## # ... with 134 more rows
fill_gaps(tsAirgap.tsibble, value = median(value), .full = TRUE) |> fabletools::autoplot()

댓글