6

Rで日付を操作する必要はあまりありませんが、これはかなり簡単だと思います。以下のような数年間の日次データといくつかの値があり、8日間ごとに関連する値の合計を取得したいのですが、最善のアプローチは何ですか?

あなたが提供できるどんな助けも大いに感謝されるでしょう!

 str(temp)
'data.frame':648 obs. of  2 variables:
 $ Date : Factor w/ 648 levels "2001-03-24","2001-03-25",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ conv2: num  -3.93 -6.44 -5.48 -6.09 -7.46 ...

head(temp)
Date              amount
24/03/2001  -3.927020472
25/03/2001  -6.4427004
26/03/2001  -5.477592528
27/03/2001  -6.09462162
28/03/2001  -7.45666902
29/03/2001  -6.731540928
30/03/2001  -6.855206184
31/03/2001  -6.807210228
1/04/2001   -5.40278802

集計関数を使用しようとしましたが、いくつかの理由で機能せず、間違った方法で集計されます。

z <- aggregate(amount ~ Date, timeSequence(from =as.Date("2001-03-24"),to =as.Date("2001-03-29"), by="day"),data=temp,FUN=sum)
4

5 に答える 5

6

xts私はそのような操作のためのパッケージを好みます。

  1. 私はあなたのデータを動物園のオブジェクトとして読みました。フォーマットオプションの柔軟性を参照してください。

    library(xts)
    ts.dat <- read.zoo(text ='Date              amount
    24/03/2001  -3.927020472
    25/03/2001  -6.4427004
    26/03/2001  -5.477592528
    27/03/2001  -6.09462162
    28/03/2001  -7.45666902
    29/03/2001  -6.731540928
    30/03/2001  -6.855206184
    31/03/2001  -6.807210228
    1/04/2001   -5.40278802',header=TRUE,format = '%d/%m/%Y')
    
  2. 次に、指定された期間のインデックスを抽出します

    ep <- endpoints(ts.dat,'days',k=8)
    
  3. 最後に、各インデックスの時系列に関数を適用します。

    period.apply(x=ts.dat,ep,FUN=sum )
    2001-03-29 2001-04-01 
    -36.13014  -19.06520 
    
于 2013-01-07T08:15:44.570 に答える
5

コマンドで使用cut()しますaggregate()

いくつかのサンプルデータ:

set.seed(1)
mydf <- data.frame(
    DATE = seq(as.Date("2000/1/1"), by="day", length.out = 365),
    VALS = runif(365, -5, 5))

さて、集計。詳細?cut.Dateはをご覧ください。次を使用して、各グループに必要な日数を指定できますcut

output <- aggregate(VALS ~ cut(DATE, "8 days"), mydf, sum)
list(head(output), tail(output))
# [[1]]
#   cut(DATE, "8 days")      VALS
# 1          2000-01-01  8.242384
# 2          2000-01-09 -5.879011
# 3          2000-01-17  7.910816
# 4          2000-01-25 -6.592012
# 5          2000-02-02  2.127678
# 6          2000-02-10  6.236126
# 
# [[2]]
#    cut(DATE, "8 days")       VALS
# 41          2000-11-16 17.8199285
# 42          2000-11-24 -0.3772209
# 43          2000-12-02  2.4406024
# 44          2000-12-10 -7.6894484
# 45          2000-12-18  7.5528077
# 46          2000-12-26 -3.5631950
于 2013-01-07T06:53:20.420 に答える
2

rollapply。zooパッケージには、ローリング適用機能があり、非ローリング集計も実行できます。まず、次のようにtempデータフレームを動物園に変換しますread.zoo

library(zoo)
zz <- read.zoo(temp)

そしてそのちょうど:

rollapply(zz, 8, sum, by = 8)

by = 8代わりにローリングトータルが必要な場合は ドロップしてください。

(質問の2つのバージョンはtemp同じではないことに注意してください。列見出しが異なり、日付列の形式も異なります。str(temp)ここでは出力バージョンを想定しています。バージョンの場合は、に引数をhead(temp)追加する必要があります。)format = "%d/%m/%Y"read.zoo

集計。これは、外部パッケージを使用しないソリューションです。aggregate元のデータフレームに基づい て使用します。

ix <- 8 * ((1:nrow(temp) - 1) %/% 8 + 1)
aggregate(temp[2], list(period = temp[ix, 1]), sum)

ix次のようになります。

> ix
[1]  8  8  8  8  8  8  8  8 16

したがって、最初の8行、次の8行などのインデックスをグループ化します。

于 2013-01-07T12:25:31.973 に答える
1

これらは日付クラスの変数ではありません。(これらが因子としてラベル付けされているという事実は言うまでもなく、自尊心のあるプログラムはそのような日付を表示しません。)[後でこれらが同じオブジェクトではないことに気づきました。]さらに、timeSequence関数(少なくともtimeDateパッケージ)もDateクラスベクトルを返しません。したがって、2つの異なる非日付オブジェクトを適切な方法で整列させるための「正しい方法」があるというあなたの期待は、考えられていません。皮肉なことに、temp $ Date列を使用するだけで、次のように機能します。

> z <- aggregate(amount ~ Date, data=temp , FUN=sum)
> z
        Date    amount
1  1/04/2001 -5.402788
2 24/03/2001 -3.927020
3 25/03/2001 -6.442700
4 26/03/2001 -5.477593
5 27/03/2001 -6.094622
6 28/03/2001 -7.456669
7 29/03/2001 -6.731541
8 30/03/2001 -6.855206
9 31/03/2001 -6.807210

しかし、8日間隔で取得するには、次を使用しますcut.Date

> z <- aggregate(temp$amount , 
                 list(Dts = cut(as.Date(temp$Date, format="%d/%m/%Y"), 
                 breaks="8 day")), FUN=sum)
> z
         Dts          x
1 2001-03-24 -49.792561
2 2001-04-01  -5.402788
于 2013-01-07T06:56:52.710 に答える
0

よりクリーンなアプローチが@Gに拡張されました。グロタンディークのアプローチ。:日付が連続しているか不連続であるかは考慮されません。合計は固定幅に基づいて計算されます。


コード

  interval = 8 # your desired date interval. 2 days, 3 days or whatevea 
  enddate = interval-1 # this sets the enddate
  nrows = nrow(z)
  z <- aggregate(.~V1,data = df,sum) # aggregate sum of all duplicate dates
  z$V1 <- as.Date(z$V1)
  data.frame ( Start.date = (z[seq(1, nrows, interval),1]),
               End.date =  z[seq(1, nrows, interval)+enddate,1],
               Total.sum = rollapply(z$V2, interval, sum, by = interval, partial = TRUE))

出力

   Start.date   End.date   Total.sum
1  2000-01-01 2000-01-08   9.1395926
2  2000-01-09 2000-01-16  15.0343960
3  2000-01-17 2000-01-24   4.0974712
4  2000-01-25 2000-02-01   4.1102645
5  2000-02-02 2000-02-09 -11.5816277

データ

  df <- data.frame(
  V1 = seq(as.Date("2000/1/1"), by="day", length.out = 365),
  V2 = runif(365, -5, 5))
于 2017-02-04T00:10:19.103 に答える