さて、最初にいくつかのテストデータを生成するためのコード。これにより、100個のランダムIDが作成され、それぞれに対して2年間の期間から20か月がランダムな値とともに選択されます。その後、注文はさらに楽しくなるようにシャッフルされます。
## Generate some IDs
ids <- sample(1000, 100)
## Generate the data
data <- do.call(rbind,
lapply(ids,
function(id)
data.frame(ID = id,
Date = sample(as.Date(paste(rep(c(2008:2009), each=12),
1:12, 1, sep="-")),
20),
Value = sample(1000, 20))))
## Shuffle
data <- data[sample(nrow(data), nrow(data)),]
これが私にとってどのように見えるかです:
> head(data)
ID Date Value
1007 205 2008-07-01 235
1391 840 2008-12-01 509
918 278 2009-12-01 951
1213 945 2009-03-01 842
1369 766 2009-07-01 555
798 662 2008-12-01 531
では、IDを繰り返し処理して、各IDの各月の差分を見つけましょう。その前に、月を数値に変換して、違いを見つけやすくします(これは少し汚れていますが、Dateオブジェクトで算術演算を行うためのより良い方法を知っている人はいますか?)。これはyear * 12 + month
、通常の算術演算が機能するようにするためのものです。
data$Month <- as.POSIXlt(data$Date)$mon + as.POSIXlt(data$Date)$year * 12
次に、差を計算します。
by.id <- by(data, data$ID, function(x) {
## Sort by month.
x <- x[order(x$Month),]
## Compute the month and value differences, taking care to pad the edge case.
data.frame(ID=x$ID,
Date = x$Date,
Month.diff=c(0, diff(x$Month)),
Value.diff=c(0,diff(x$Value)))
})
by.id <- do.call(rbind, by.id)
結果は次のようになります。
> head(by.id)
ID Date Month.diff Value.diff
4.1 4 2008-02-01 0 0
4.2 4 2008-03-01 1 123
4.3 4 2008-05-01 2 -94
4.4 4 2008-06-01 1 -243
4.5 4 2008-08-01 2 -327
4.6 4 2008-10-01 2 656
連続する月の差が1より大きい場合、月は隣接していないため、値をゼロに設定する必要があります。
by.id$Value.diff <- ifelse(by.id$Month.diff == 1,
by.id$Value.diff,
0)
最後に、月ごとに繰り返し、上位と下位のNの差を取ります(テストデータセットがかなり小さいため、ここではNを100ではなく10に設定します)。
by.month <- by(by.id, by.id$Date, function(x) {
## Sort the data in each month
x <- x[order(x$Value.diff),]
## Take the top and bottom and label them accordingly.
cbind(rbind(head(x, 10), tail(x, 10)),
type=rep(c("min", "max"), each=10))
})
そして、そこにあります。結果の例を次に示します。
> by.month[[24]]
ID Date Month.diff Value.diff type
130.20 130 2009-12-01 1 -951 min
415.20 415 2009-12-01 1 -895 min
662.20 662 2009-12-01 1 -878 min
107.20 107 2009-12-01 1 -744 min
824.20 824 2009-12-01 1 -731 min
170.20 170 2009-12-01 1 -719 min
502.20 502 2009-12-01 1 -714 min
247.20 247 2009-12-01 1 -697 min
789.20 789 2009-12-01 1 -667 min
132.20 132 2009-12-01 1 -653 min
64.20 64 2009-12-01 1 622 max
82.20 82 2009-12-01 1 647 max
381.20 381 2009-12-01 1 698 max
303.20 303 2009-12-01 1 700 max
131.20 131 2009-12-01 1 751 max
221.20 221 2009-12-01 1 765 max
833.20 833 2009-12-01 1 791 max
806.20 806 2009-12-01 1 806 max
780.20 780 2009-12-01 1 843 max
912.20 912 2009-12-01 1 929 max