在R中按周分组

时间:2016-11-14 04:01:53

标签: r date-arithmetic week-number

我希望根据他们的一周标记我的数据。这是我的数据:

df2 <- structure(list(Order_Date = structure(c(16735, 16805, 16753, 
16830, 17075, 17009, 17085, 16740, 16891, 16750, 16820, 16849, 
16906, 16929, 16746, 16731, 16786, 16873, 16895, 16931), class = "Date")), .Names = "Order_Date", row.names = c(NA, 
-20L), class = "data.frame")

我尝试根据一周(第0周,第1周和......)来标记它们,我希望在一周之后对我的数据进行分组

我试过这个:

# order by data
library (dplyr)
df2<- arrange(df2, Order_Date)


# label them by week
$df2$week <- cumsum(weekdays(df2$Order_Date) == "Friday")

它没有给我正确的结果,我有以下输出,这很奇怪

   Order_Date week
1  2015-10-27    0
2  2016-01-05    0
3  2015-11-14    0
4  2016-01-30    0
5  2016-10-01    0
6  2016-07-27    0
7  2016-10-11    0
8  2015-11-01    0
9  2016-03-31    0
10 2015-11-11    0
11 2016-01-20    0
12 2016-02-18    0
13 2016-04-15    1
14 2016-05-08    1
15 2015-11-07    1
16 2015-10-23    2
17 2015-12-17    2
18 2016-03-13    2
19 2016-04-04    2
20 2016-05-10    2

理想情况下,我希望获得此输出:

  Order_Date   label
1  2015-10-23   0
2  2015-10-27   0
3  2015-11-01   1
4  2015-11-07   2
5  2015-11-11   2
6  2015-11-14   3
7  2015-12-17   8
8  2016-01-05   10

因为第8行出现在第1行后10周,但是生成以下内容的解决方案是我的第二个替代方案,显示这些数据不在同一周:

  Order_Date   label
1  2015-10-23   0
2  2015-10-27   0
3  2015-11-01   1
4  2015-11-07   2
5  2015-11-11   2
6  2015-11-14   3
7  2015-12-17   4
8  2016-01-05   5

3 个答案:

答案 0 :(得分:4)

cut.Date采用间隔规范(请参阅?cut.Date)。

您的数据涵盖整整一年,因此除非您想重新命名这些周,否则这将计算实际的周数:

library(dplyr)
df2 %>% 
  mutate(week = cut.Date(Order_Date, breaks = "1 week", labels = FALSE)) %>% 
  arrange(Order_Date)

#>    Order_Date week
#> 1  2015-10-23    1
#> 2  2015-10-27    2
#> 3  2015-11-01    2
#> 4  2015-11-07    3
#> 5  2015-11-11    4
#> 6  2015-11-14    4
#> 7  2015-12-17    9
#> 8  2016-01-05   12
#> 9  2016-01-20   14
#> 10 2016-01-30   15
#> 11 2016-02-18   18
#> 12 2016-03-13   21
#> 13 2016-03-31   24
#> 14 2016-04-04   25
#> 15 2016-04-15   26
#> 16 2016-05-08   29
#> 17 2016-05-10   30
#> 18 2016-07-27   41
#> 19 2016-10-01   50
#> 20 2016-10-11   52

答案 1 :(得分:3)

下面的代码计算相对于数据中最小周的当前周。 week2使用模运算来使代码更简洁,尽管周数不总是与使用lubridate函数直接计算年和周数相对应。

library(dplyr)
library(lubridate)

df2 %>% mutate(week = (year(Order_Date) - year(min(Order_Date)))*52 + 
                 week(Order_Date) - week(min(Order_Date)),
               week2 = (as.numeric(Order_Date) %/% 7) - (as.numeric(min(Order_Date)) %/% 7)) %>%
  arrange(Order_Date)
   Order_Date week week2
1  2015-10-23    0     0
2  2015-10-27    0     0
3  2015-11-01    1     1
4  2015-11-07    2     2
5  2015-11-11    2     2
6  2015-11-14    3     3
7  2015-12-17    8     8
8  2016-01-05   10    10
9  2016-01-20   12    12
10 2016-01-30   14    14
11 2016-02-18   16    17
12 2016-03-13   20    20
13 2016-03-31   22    23
14 2016-04-04   23    23
15 2016-04-15   25    25
16 2016-05-08   28    28
17 2016-05-10   28    28
18 2016-07-27   39    39
19 2016-10-01   49    49
20 2016-10-11   50    50

答案 2 :(得分:0)

或者,您可以使用ISOweek包将日期转换为ISOweek格式,然后使用它来过滤输出。

使用ISOweek包的示例代码:

library(ISOweek)
x <- paste0(2000:2017, "-01-01")
x <- as.Date(x)
y <- ISOweek(x)
print(y)