通过在R中对连续月份进行分组来制作列表

时间:2016-09-04 18:09:44

标签: r split time-series subset

这听起来很简单,但很难搞清楚。我有一个数据框(S),其中一列填充数字月(1-12,即1月 - 12月):

S$month
 [1]  6  7 12  1  2  3  4  5  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10
[27] 11 12  2  3  4  6 10 11 12  1  2  3  5  6  7  7 

我想将数据框拆分成一个列表,因为连续几个月的分组如下所示:

S[[1]]$month
[1]  6  7
S[[2]]$month
[1]  12  1  2  3  4  5  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10
[25] 11 12
S[[3]]$month
[1] 2  3  4
S[[4]]$month
[1] 6
S[[5]]$month
[1] 10 11 12  1  2  3
S[[6]]$month
[1] 5  6  7  7

请注意,有几个月是重复的,因为已经进行了多次测量。

除了写下很多内容之外,有没有简单的方法可以做到: S[[1]]<-S[c(1:2),]; S[[2]]<-S[c(3:28),];等等......因为那效率很低!

2 个答案:

答案 0 :(得分:3)

您可以使用cumsumdiff创建群组变量,并使用split功能将您的矢量转换为连续月份列表:

split(month, cumsum(!c(1, diff(month)) %in% c(0, 1, -11)))
# by using c(0, 1, -11), (12, 1) which is the only consecutive case which can have diff of 
# -11 and consecutive same months are also considered as legitimate consecutive order.

# $`0`
# [1] 6 7

# $`1`
# [1] 12  1  2  3  4  5  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11 12

# $`2`
# [1] 2 3 4

# $`3`
# [1] 6

# $`4`
# [1] 10 11 12  1  2  3

# $`5`
# [1] 5 6 7 7

答案 1 :(得分:0)

我们可以通过编程方式执行此操作,而不是依赖diff的输出。

with(S, split(month, cumsum(c(TRUE, diff(cumsum(c(FALSE, 
         (month==12)[-length(month)]))*12 + month)>1))))
#$`1`
#[1] 6 7

#$`2`
#[1] 12  1  2  3  4  5  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11 12

#$`3`
#[1] 2 3 4

#$`4`
#[1] 6

#$`5`
#[1] 10 11 12  1  2  3

#$`6`
#[1] 5 6 7 7

数据

S <- structure(list(month = c(6, 7, 12, 1, 2, 3, 4, 5, 5, 6, 7, 8, 
9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 2, 3, 4, 
6, 10, 11, 12, 1, 2, 3, 5, 6, 7, 7)), .Names = "month", row.names = c(NA, 
-42L), class = "data.frame")