[英]Aggregate daily level data to weekly level in R
我有一個巨大的數據集,類似於以下可重現的樣本數據。
Interval value
1 2012-06-10 552
2 2012-06-11 4850
3 2012-06-12 4642
4 2012-06-13 4132
5 2012-06-14 4190
6 2012-06-15 4186
7 2012-06-16 1139
8 2012-06-17 490
9 2012-06-18 5156
10 2012-06-19 4430
11 2012-06-20 4447
12 2012-06-21 4256
13 2012-06-22 3856
14 2012-06-23 1163
15 2012-06-24 564
16 2012-06-25 4866
17 2012-06-26 4421
18 2012-06-27 4206
19 2012-06-28 4272
20 2012-06-29 3993
21 2012-06-30 1211
22 2012-07-01 698
23 2012-07-02 5770
24 2012-07-03 5103
25 2012-07-04 775
26 2012-07-05 5140
27 2012-07-06 4868
28 2012-07-07 1225
29 2012-07-08 671
30 2012-07-09 5726
31 2012-07-10 5176
我想將此數據聚合到每周級別以獲得類似於以下內容的輸出:
Interval value
1 Week 2, June 2012 *aggregate value for day 10 to day 14 of June 2012*
2 Week 3, June 2012 *aggregate value for day 15 to day 21 of June 2012*
3 Week 4, June 2012 *aggregate value for day 22 to day 28 of June 2012*
4 Week 5, June 2012 *aggregate value for day 29 to day 30 of June 2012*
5 Week 1, July 2012 *aggregate value for day 1 to day 7 of July 2012*
6 Week 2, July 2012 *aggregate value for day 8 to day 10 of July 2012*
如何在不編寫長代碼的情況下輕松實現這一目標?
如果您的意思是按周計算“價值”的總和,我認為最簡單的方法是按照 GSee 的建議將數據轉換為 xts 對象:
data <- as.xts(data$value,order.by=as.Date(data$interval))
weekly <- apply.weekly(data,sum)
[,1]
2012-06-10 552
2012-06-17 23629
2012-06-24 23872
2012-07-01 23667
2012-07-08 23552
2012-07-10 10902
我將輸出的格式作為練習留給您:-)
如果您使用的是數據框,則可以使用tidyquant
包輕松完成此tidyquant
。 使用tq_transmute
函數,該函數應用突變並返回一個新的數據幀。 選擇“值”列並應用 xts 函數apply.weekly
。 附加參數FUN = sum
將按周獲得聚合。
library(tidyquant)
df
#> # A tibble: 31 x 2
#> Interval value
#> <date> <int>
#> 1 2012-06-10 552
#> 2 2012-06-11 4850
#> 3 2012-06-12 4642
#> 4 2012-06-13 4132
#> 5 2012-06-14 4190
#> 6 2012-06-15 4186
#> 7 2012-06-16 1139
#> 8 2012-06-17 490
#> 9 2012-06-18 5156
#> 10 2012-06-19 4430
#> # ... with 21 more rows
df %>%
tq_transmute(select = value,
mutate_fun = apply.weekly,
FUN = sum)
#> # A tibble: 6 x 2
#> Interval value
#> <date> <int>
#> 1 2012-06-10 552
#> 2 2012-06-17 23629
#> 3 2012-06-24 23872
#> 4 2012-07-01 23667
#> 5 2012-07-08 23552
#> 6 2012-07-10 10902
我剛剛遇到這個老問題,因為它被用作欺騙目標。
不幸的是,所有贊成的答案(除了konvas和一個現已刪除的答案)都提出了按一年中的一周聚合數據的解決方案,而 OP 已要求按月中的一周聚合。
正如此處、此處和此處所討論的,一年中的一周和一個月中的一周的定義是不明確的。
但是,OP 表示他希望將每個月的第 1 到 7 天計算為該月的第 1 周,將第 8 到 14 天計算為該月的第 2 周,等等。請注意,第 5 周是大多數情況下的存根僅由 2 或 3 天組成的月份(如果沒有閏年,二月份除外)。
准備好基礎后,這里是這種聚合的data.table
解決方案:
library(data.table)
DT[, .(value = sum(value)),
by = .(Interval = sprintf("Week %i, %s",
(mday(Interval) - 1L) %/% 7L + 1L,
format(Interval, "%b %Y")))]
Interval value 1: Week 2, Jun 2012 18366 2: Week 3, Jun 2012 24104 3: Week 4, Jun 2012 23348 4: Week 5, Jun 2012 5204 5: Week 1, Jul 2012 23579 6: Week 2, Jul 2012 11573
我們可以通過以下方式驗證我們是否選擇了正確的間隔
DT[, .(value = sum(value),
date_range = toString(range(Interval))),
by = .(Week = sprintf("Week %i, %s",
(mday(Interval) -1L) %/% 7L + 1L,
format(Interval, "%b %Y")))]
Week value date_range 1: Week 2, Jun 2012 18366 2012-06-10, 2012-06-14 2: Week 3, Jun 2012 24104 2012-06-15, 2012-06-21 3: Week 4, Jun 2012 23348 2012-06-22, 2012-06-28 4: Week 5, Jun 2012 5204 2012-06-29, 2012-06-30 5: Week 1, Jul 2012 23579 2012-07-01, 2012-07-07 6: Week 2, Jul 2012 11573 2012-07-08, 2012-07-10
這符合 OP 的規范。
library(data.table)
DT <- fread(
"rn Interval value
1 2012-06-10 552
2 2012-06-11 4850
3 2012-06-12 4642
4 2012-06-13 4132
5 2012-06-14 4190
6 2012-06-15 4186
7 2012-06-16 1139
8 2012-06-17 490
9 2012-06-18 5156
10 2012-06-19 4430
11 2012-06-20 4447
12 2012-06-21 4256
13 2012-06-22 3856
14 2012-06-23 1163
15 2012-06-24 564
16 2012-06-25 4866
17 2012-06-26 4421
18 2012-06-27 4206
19 2012-06-28 4272
20 2012-06-29 3993
21 2012-06-30 1211
22 2012-07-01 698
23 2012-07-02 5770
24 2012-07-03 5103
25 2012-07-04 775
26 2012-07-05 5140
27 2012-07-06 4868
28 2012-07-07 1225
29 2012-07-08 671
30 2012-07-09 5726
31 2012-07-10 5176", drop = 1L)
DT[, Interval := as.Date(Interval)]
如果你使用week
從lubridate
,你只會得到五個星期傳遞給by
。 假設dat
是您的數據,
> library(lubridate)
> do.call(rbind, by(dat$value, week(dat$Interval), summary))
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 24 552 4146 4188 3759 4529 4850
# 25 490 2498 4256 3396 4438 5156
# 26 564 2578 4206 3355 4346 4866
# 27 698 993 4868 3366 5122 5770
# 28 671 1086 3200 3200 5314 5726
這顯示了一年中第 24 周到第 28 周的摘要。 類似地,我們可以得到帶有aggregate
的均值
> aggregate(value~week(Interval), data = dat, mean)
# week(Interval) value
# 1 24 3758.667
# 2 25 3396.286
# 3 26 3355.000
# 4 27 3366.429
# 5 28 3199.500
當你說“聚合”這些值時,你的意思是取它們的總和? 假設您的數據框是d
並且假設d$Interval
是Date
類,您可以嘗試
# if d$Interval is not of class Date d$Interval <- as.Date(d$Interval)
formatdate <- function(date)
paste0("Week ", (as.numeric(format(date, "%d")) - 1) + 1,
", ", format(date, "%b %Y"))
# change "sum" to your required function
aggregate(d$value, by = list(formatdate(d$Interval)), sum)
# Group.1 x
# 1 Week 1, Jul 2012 3725.667
# 2 Week 2, Jul 2012 3199.500
# 3 Week 2, Jun 2012 3544.000
# 4 Week 3, Jun 2012 3434.000
# 5 Week 4, Jun 2012 3333.143
# 6 Week 5, Jun 2012 3158.667
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.