はじめに
R を使って時系列データの前処理を行った際、使ったコードをつらつらと書き足していく。全く同じことをPython でも行っているので、それを読みたい方はこちら。
開発環境
- R 4.0.3
- RStudio 1.4.1103
更新履歴
- 2021/02/12:初投稿。データの読み込みから欠損の確認まで。
参考にした記事
データの読み込み
データは時系列かつ多変量であるWater Treatment Plantを利用した。
必要なパッケージとデータを読み込む。
library(dplyr)
df <- read.csv(file="./water-treatment.data", header=FALSE, na.strings="?") #?を欠損値として扱う
dim(df)
[1] 527 39
ただしくデータが読み込まれた。
データの結合(複数ある場合)
データのcsvファイルが複数ある場合は、それを結合し一つのDataFrameとして扱いたい。各列の要素が同じであることをチェックしたら、
df <- bind_rows(df.1, df.2, df.3)
で結合すればよい。#今回の場合は1ファイルなので不要。
時刻化と時刻でのソート
1列目に時刻がD-日付/月/年という形式で入っているので、それをPOSIXct型に直す。Rでは、as.POSIXct
という関数があるので、それを使用する。
df[,1] <- as.POSIXct(df[,1], format="D-%d/%m/%y", tz="UTC")
df <- df[order(df[,1]),] #時刻でソートする
デフォルトだとJSTになってしまうのが多少気持ち悪いので、タイムゾーンをUTCで指定している。このデータは日付だけなので、POSIXct型ではなくDate型にしても良さそう。
df[,1] <- as.Date(df[,1], format="D-%d/%m/%y")
df <- df[order(df[,1]),] #時刻でソートする
以下はDate型として取り扱う。
データの重複の確認
データの重複が無いかをチェックする。列を直接比較する方法は難しそうなので、一旦転置し重複行を探して削除し、再度転置して戻すという方法を取る。
duplicated(t(df)) #重複の確認
今回のデータの場合全てFalse
なので重複は無し。重複があった場合は、その列番号を指定して、
df = df[,-10] #例えば10列目を削除したい場合
で削除できる。
因みに要素ではなく列名で重複を確認する場合は以下に示す。
colnames(y) %>% duplicated()
いずれにせよ、重複は
- 重複の有無を確認する。
- 重複が有った場合、データの中身を確認する(プロットしてみるなど)
- 削除するかを決める
という感じで取り扱うのが良さそう。
データのサンプル間隔を調べる
よくよくデータを見てみると等サンプルのデータではなさそうなので、サンプリング間隔のヒストグラムを作る。日付の配列を一つずらした配列を作り順次引き算していくことでデータのサンプル間隔を調べる。
dt <- as.integer( df[,1] - lag(df[,1], 1) ) #時刻の差分
hist(dt, breaks = seq(0,35,1)) #ヒストグラムにプロット
見難いので対数で取ったヒストグラムも作成する。(参考記事1)Rの場合は少し工夫が必要。
dt.data <- hist(dt, breaks = seq(0,35,1), plot=FALSE) #ヒストグラムのデータを作成
dt.data$counts <- log10(dt.data$counts) #countsを対数に直す
plot(dt.data, ylim=c(-1, 5) ,ylab='log10(Frequency)') #再度プロット
$\log_{10}(1) = 0$ の点があるせいでこちらも見難いグラフになってしまった。どなたかRできれいに対数ヒストグラムを書く方法をご存じでしたら教えて下さい!
ほとんどが一日間のサンプリングデータだが1/5程度は二日間、ごくまれに三日間、1データだけ一か月くらい(三十二日間)データが飛んでいる箇所があるよう。
これを「等サンプリングに直す」のは次回。
データの欠損の確認
このデータは欠損を含んでいる(欠損は?で表されている。)ので、その可視化を行う。列ごとに欠損の数を数え、その割合を棒グラフにする。
na.count <- apply(is.na(df), 2, sum)
na.per <- na.count / nrow(df) * 100
barplot(na.per, ylab="Percentage of NAs [%]", xlab="Columns")
ほとんどのデータは10%以下、多くても12%程度の欠損であることが分かった。
おわりに
以上、データの下準備とちょっとした分析を行った結果を示した。もし加えて何かをした場合は記事に追記していきたい。