使用列的循环值在R中对时间序列数据进行分组

时间:2015-01-29 00:34:36

标签: r data.table grouping

我有一个日常数据集,需要根据一列的循环值进行分组。我希望添加另一个包含分组标识符的列。例如,我有这组数据

YEAR = c(1900, 1900, 1900, 1901,1901, 1901, 1901, 1902, 1902, 1902, 1903)
CS = c("SUM", "SUM", "SUM", "SUM", "SPR", "SPR", "SPR",  "SPR", "SPR", "SPR", "SPR")
DAS = c(1, 2, 3, 4, 1, 2, 3,1, 2, 3, 4)


mydt <- data.table (YEAR, CS, DAS)

    YEAR  CS DAS
 1: 1900 SUM   1
 2: 1900 SUM   2
 3: 1900 SUM   3
 4: 1901 SUM   4
 5: 1901 SPR   1
 6: 1901 SPR   2
 7: 1901 SPR   3
 8: 1902 SPR   1
 9: 1902 SPR   2
10: 1902 SPR   3
11: 1903 SPR   4

我想添加另一个包含基于DAS值的分组的列,如下所示:

    YEAR  CS DAS     GRP
 1: 1900 SUM   1 1900SUM
 2: 1900 SUM   2 1900SUM
 3: 1900 SUM   3 1900SUM
 4: 1901 SUM   4 1900SUM
 5: 1901 SPR   1 1901SPR
 6: 1901 SPR   2 1901SPR
 7: 1901 SPR   3 1901SPR
 8: 1902 SPR   1 1902SPR
 9: 1902 SPR   2 1902SPR
10: 1902 SPR   3 1902SPR
11: 1903 SPR   4 1902SPR

显然,GRP只是YEAR和CS的串联,虽然任何标识符,比如组号,都可以。分组是基于DAS的值何时返回到1.我使用for循环来执行此操作并且运行良好

group <- function(df) {
    for (i in 1: nrow(df)) {
        if (df$DAS[i]== 1) {
            nval<- paste0(df$YEAR[i], df$CS[i])
        }
        df$GRP[i] <- nval
    }
    df
}

我的问题是,当使用数百万行时,它非常慢。有没有办法以更快的方式实现它?

更新 正如colemand77所指出的,分组并不完全基于YEAR和CS的组合,而是基于DAS的值何时返回到1的情况。有时YEAR和CS的值不同但它们仍然属于同一个因此,DAS的周期属于一个群体。

1 个答案:

答案 0 :(得分:0)

所以,只是为了突出Arun的回答:

mydt[, GRP := .GRP, by=c("YEAR", "CS")]

但是也指出上面的GRP不是YEARCS的串联,如你所说的......如果这只是一个错误印记,那么Arun的评论是正确的。如果不是,那么你可能需要重申,因为Arun的回答会产生意想不到的结果。

尝试以下操作,还没有计时。 ifelse可能不会尽可能快,但我能做得最快。如果它缓慢让我知道,我们将重新哈希它:

mydt[DAS == 1,GRP := .GRP, by = DAS][,GRP2 := cumsum(ifelse(is.na(GRP),0,GRP))]