2017-02-10 8 views
0

私は過去6ヶ月にわたりデータセットのローリング・平均を作成しようとしています。 データは日々のもので、100,000を超える行があり、そこからサンプルを提供しました。観測数の異なるローリング・平均

# A tibble: 100 × 5 
     ID MONTH  DATE VALUE R_MEAN 
    <fctr> <dbl>  <date> <dbl> <dbl> 
1  634 20160200 2016-02-03  2 0.000000 
2 1700 20150300 2015-03-02  3 0.000000 
3 1700 20150400 2015-04-01  7 3.000000 
4 1700 20150400 2015-04-09  1 5.000000 
5 1700 20150700 2015-07-02 26 3.666667 
6 1700 20150800 2015-08-03  1 9.250000 
7 1700 20150900 2015-09-01  2 7.600000 
8 1700 20151000 2015-10-01  5 7.400000 
9 1700 20151000 2015-10-07 10 7.833333 
10 1700 20151100 2015-11-02  8 8.800000 
# ... with 90 more rows 

私の目標は、IDのために、たとえばので、過去6カ月間にわたり移動平均を作成することです:20160101のXおよびDATE値Iは、同じIDを持つすべての行の平均値を取得したいとここでDATE値は20150601〜20160101です。以前の値が利用できない場合、私は平均値をゼロと見なします。

私はある種の拡張グリッドアプローチを使用すると考えましたが、私はID(30,000に近い)が多いため、グリッドを2年間にわたって毎日拡張すると膨大なグリッドになります。

答えて

2

私はdplyrを使用しています。 I inner_joinそれ自体のテーブルを作成し、ソースデータの行ごとに関連する前の行をフィルタリングし、平均値を計算します。

最後に、left_join処理データの元のデータをNAに置き換えて、​​3210を置き換えます。

6ヶ月のウィンドウは、DATEから182日を引くことによって計算されます。 lubridateを使用して、数ヶ月で期間を設定することもできます。個人的に私は固定された日の窓で作業することを好みます、それは毎月の異なる日数に依存しません。

str <- ' 
row ID MONTH DATE VALUE R_MEAN 
1 634 20160200 2016-02-03  2 0.000000 
2 1700 20150300 2015-03-02  3 0.000000 
3 1700 20150400 2015-04-01  7 3.000000 
4 1700 20150400 2015-04-09  1 5.000000 
5 1700 20150700 2015-07-02 26 3.666667 
6 1700 20150800 2015-08-03  1 9.250000 
7 1700 20150900 2015-09-01  2 7.600000 
8 1700 20151000 2015-10-01  5 7.400000 
9 1700 20151000 2015-10-07 10 7.833333 
10 1700 20151100 2015-11-02  8 8.800000 
' 

file <- textConnection(str) 

raw <- read.table(file, header = T) 

library(dplyr) 

df <- raw %>% mutate(DATE = as.Date(DATE,'%Y-%m-%d')) 

prev <- df %>% inner_join(df, by = 'ID') %>% 
    filter(DATE.y > DATE.x-182, DATE.y < DATE.x) %>% 
    group_by(row.x) %>% summarise(meanVALUE = mean(VALUE.y)) %>% 
    rename(row = row.x) 

df %>% left_join(prev, by='row') %>% mutate(meanVALUE = coalesce(meanVALUE,0)) 

結果:

row ID MONTH  DATE VALUE R_MEAN meanVALUE 
1 1 634 20160200 2016-02-03  2 0.000000 0.000000 
2 2 1700 20150300 2015-03-02  3 0.000000 0.000000 
3 3 1700 20150400 2015-04-01  7 3.000000 3.000000 
4 4 1700 20150400 2015-04-09  1 5.000000 5.000000 
5 5 1700 20150700 2015-07-02 26 3.666667 3.666667 
6 6 1700 20150800 2015-08-03  1 9.250000 9.250000 
7 7 1700 20150900 2015-09-01  2 7.600000 8.750000 
8 8 1700 20151000 2015-10-01  5 7.400000 7.500000 
9 9 1700 20151000 2015-10-07 10 7.833333 7.000000 
10 10 1700 20151100 2015-11-02  8 8.800000 8.800000 
+0

素晴らしい!これはすごくうまくいった! – Michael

0

は、たぶんこのことができます:ここで

for (i in 1:levels(df$ID)) 
    mean(df$value[df$DATE>(Sys.date()-182) & 
        df$ID==levels(df$ID)[i]], 
      na.rm=T) 
+0

私は、各行のDATEの値のため、過去6ヶ月間のローリング平均を持っていると思います。だから私は今日に基づいて過去6ヶ月を見てみたくない。あなたの回答をありがとう。 – Michael

関連する問題