1

TSVには次のような時系列のデータがあります。

ID \t Date \t Value
-------------------------------
1234567 \t 2009-01-01T00:00:00.000Z \t 121
12131 \t 2009-06-01T00:00:00.000Z \t 151
12131 \t 2009-07-01T00:00:00.000Z \t 15153
...

RAMに簡単に収まりますが、Excelには大きすぎます。

IDごとに1か月に1つの値がありますが、すべてのIDに12か月すべてのエントリがあるわけではありません。

データは12か月に及びますが、すべてのIDがすべて12か月であるとは限りません。各IDのデータを調べたいのですが、前月のエントリがある場合は、当月から前月を引いたものを新しい列に格納して、デルタを取得します。前月のエントリがない場合は、0を返します。次に、各月について、IDとともに、これらのデルタの正と負の上位100個が必要です。

これはRで行いたいのですが、Excelでは難しく、クラッシュし続けるからです。R、Rattleなどをインストールして、基本的な例を試しましたが、...学習曲線は急です。私は本当にいくつかの助けをいただければ幸いです:)

4

3 に答える 3

7

不足しているすべての月を追加することから始めます。

all_combs <- expand.grid(
  ID = unique(data$ID),
  Date = unique(data$Date))

data <- merge(data, all_combs, by = c("ID", "Date"), all = T)
# Ensure data ordered by date
data <- data[with(data, order(ID, Date)), ]

次に、デルタの列を追加します(diffで計算)

library(plyr)
data <- ddply(data, "ID", transform, delta = c(NA, diff(Value)))

最後に、欠落しているデルタを削除し、それらの値で並べ替えて、各グループ内の上位10と下位10を抽出します。

changed <- subset(data, !is.na(delta))
changed <- changed[with(changed, order(ID, delta)), ]

# Select top 100 for each
top10 <- ddply(changed, "ID", function(df) {
 rbind(head(df, 10), tail(df, 10))
})
于 2009-12-23T08:49:22.173 に答える
4

さて、最初にいくつかのテストデータを生成するためのコード。これにより、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
于 2009-12-23T06:04:15.517 に答える
1

開始する擬似コード:

For Each ID
  If Previous month data Exists 
    compute Diff
  Else diff = 0
return diff

For Each Month
  Max 100 (Positive)
  Min 100 (Negative)

#Realish Code
dataset$diff <- lappply(dataset,function(ID,month,value){IF dataset[month-1] = TRUE{value-(value[month-1]})})
#This gets tricky since you need to know the month and what the previous month is in a format you can test
于 2009-12-23T04:25:36.307 に答える