How to multiply data.frame by weeks and then summarize?

Let's say I have data for several years that look like this

# 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

I would like to summarize the "income" for each week (Sunday to Saturday). I am currently doing the following:

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

However, I would like to get a more reliable approach, which will automatically be summarized by week. I can’t figure out how to automatically multiply data in a few weeks. Any help would be greatly appreciated.

+5
source share
7 answers

This decision is influenced by @Andrie and @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
0
source

First use formatto convert your dates to the number of weeks, then plyr::ddply()to calculate the summaries:

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 .


EDIT:

, , 7, , . (, , , , 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

, . .

+8

, dplyr. cut(breaks = "week"), format(), .

library(dplyr)
df %>% group_by(week = cut(date, "week")) %>% mutate(weekly_income = sum(income))
+6

I Googled " 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 .

+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)], .

+1

df.index = df ['week'] # dt variable as index

df.resample ('W'). sum () #sum using resample

0
source

With dplyr:

df %>% 
  arrange(date) %>%
  mutate(week = as.numeric(date - date[1])%/%7) %>%
  group_by(week) %>%
  summarise(weekincome= sum(income))

Instead of the date [1], you can have any date when you want to start your weekly study.

0
source

All Articles