簡體   English   中英

將每日級別的數據聚合到 R 中的每周級別

[英]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)]

如果你使用weeklubridate ,你只會得到五個星期傳遞給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$IntervalDate類,您可以嘗試

# 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM