10

次のような数年分のデータがあるとしましょう

# load date package and set random seed
library(lubridate)
set.seed(42)

# create data.frame of dates and income
date <- seq(dmy("26-12-2010"), dmy("15-01-2011"), by = "days")
df <- data.frame(date = date, 
                 wday = wday(date),
                 wday.name = wday(date, label = TRUE, abbr = TRUE),
                 income = round(runif(21, 0, 100)),
                 week = format(date, format="%Y-%U"),
                 stringsAsFactors = FALSE)

#          date wday wday.name income    week
# 1  2010-12-26    1       Sun     91 2010-52
# 2  2010-12-27    2       Mon     94 2010-52
# 3  2010-12-28    3      Tues     29 2010-52
# 4  2010-12-29    4       Wed     83 2010-52
# 5  2010-12-30    5     Thurs     64 2010-52
# 6  2010-12-31    6       Fri     52 2010-52
# 7  2011-01-01    7       Sat     74 2011-00
# 8  2011-01-02    1       Sun     13 2011-01
# 9  2011-01-03    2       Mon     66 2011-01
# 10 2011-01-04    3      Tues     71 2011-01
# 11 2011-01-05    4       Wed     46 2011-01
# 12 2011-01-06    5     Thurs     72 2011-01
# 13 2011-01-07    6       Fri     93 2011-01
# 14 2011-01-08    7       Sat     26 2011-01
# 15 2011-01-09    1       Sun     46 2011-02
# 16 2011-01-10    2       Mon     94 2011-02
# 17 2011-01-11    3      Tues     98 2011-02
# 18 2011-01-12    4       Wed     12 2011-02
# 19 2011-01-13    5     Thurs     47 2011-02
# 20 2011-01-14    6       Fri     56 2011-02
# 21 2011-01-15    7       Sat     90 2011-02

各週 (日曜日から土曜日まで) の「収入」を合計したいと思います。現在、私は次のことを行っています。

Weekending 2011-01-01 = sum(df$income[1:7]) = 487
Weekending 2011-01-08 = sum(df$income[8:14]) = 387
Weekending 2011-01-15 = sum(df$income[15:21]) = 443

ただし、週ごとに自動的に合計される、より堅牢なアプローチが必要です。データを自動的に週にサブセット化する方法がわかりません。どんな助けでも大歓迎です。

4

7 に答える 7

9

最初formatに日付を週番号に変換するために使用し、次にplyr::ddply()要約を計算します。

library(plyr)
df$week <- format(df$date, format="%Y-%U")
ddply(df, .(week), summarize, income=sum(income))
     week income
1 2011-52    413
2 2012-01    435
3 2012-02    379

の詳細については、特に週番号を定義するビットをformat.date参照してください。?strptime%U


編集:

変更されたデータと要件が与えられた場合、1 つの方法は、日付を 7 で割り、週を示す数値を取得することです。(より正確には、1 週間の秒数で割ると、エポック (デフォルトでは 1970-01-01) からの週数が得られます。

コード内:

df$week <- as.Date("1970-01-01")+7*trunc(as.numeric(df$date)/(3600*24*7))
library(plyr)
ddply(df, .(week), summarize, income=sum(income))

        week income
1 2010-12-23    298
2 2010-12-30    392
3 2011-01-06    294
4 2011-01-13    152

週の境界が日曜日であることを確認していません。これを確認し、適切なオフセットを数式に挿入する必要があります。

于 2012-07-09T13:34:26.950 に答える
1

パッケージrollapplyから試してください:zoo

rollapply(df$income, width=7, FUN = sum, by = 7)
# [1] 487 387 443

または、パッケージperiod.sumから使用します。xts

period.sum(xts(df$income, order.by=df$date), which(df$wday %in% 7))
#            [,1]
# 2011-01-01  487
# 2011-01-08  387
# 2011-01-15  443

または、必要な形式で出力を取得するには、次のようにします。

data.frame(income = period.sum(xts(df$income, order.by=df$date), 
                               which(df$wday %in% 7)),
           week = df$week[which(df$wday %in% 7)])
#            income    week
# 2011-01-01    487 2011-00
# 2011-01-08    387 2011-01
# 2011-01-15    443 2011-02

最初の週は と表示されている2011-00ことに注意してください。これは、データにそのように入力されているためです。week = df$week[which(df$wday %in% 1)]出力に一致する which を使用することもできます。

于 2012-07-09T17:01:52.800 に答える
1

私は「週日を週Rにグループ化する」とグーグルで検索し、このSOの質問に出くわしました。複数の年があるとおっしゃっていますので、週番号と年の両方についていく必要があると思いますので、そこで回答を修正しましたformat(date, format = "%U%y")

使用中は次のようになります。

library(plyr) #for aggregating
df <- transform(df, weeknum = format(date, format = "%y%U"))
ddply(df, "weeknum", summarize, suminc = sum(income))
#----
  weeknum suminc
1    1152    413
2    1201    435
3    1202    379

?strptimeすべての形式の略語については、を参照してください。

于 2012-07-09T13:44:56.970 に答える
0

このソリューションは、@Andrie と @Chase の影響を受けています。

# load plyr 
library(plyr)

# format weeks as per requirement (replace "00" with "52" and adjust corresponding year)
tmp <- list()
tmp$y <- format(df$date, format="%Y")
tmp$w <- format(df$date, format="%U")
tmp$y[tmp$w=="00"] <- as.character(as.numeric(tmp$y[tmp$w=="00"]) - 1)
tmp$w[tmp$w=="00"] <- "52"
df$week <- paste(tmp$y, tmp$w, sep = "-")

# get summary
df2 <- ddply(df, .(week), summarize, income=sum(income))

# include week ending date
tmp$week.ending <- lapply(df2$week, function(x) rev(df[df$week==x, "date"])[[1]])
df2$week.ending <- sapply(tmp$week.ending, as.character)

#      week income week.ending
# 1 2010-52    487  2011-01-01
# 2 2011-01    387  2011-01-08
# 3 2011-02    443  2011-01-15
于 2012-07-09T15:18:55.687 に答える