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

Grouping time series data in R using cyclic values of a column

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

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 returns 的值何时为 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 returns 的值何时为 1。有些情况下 YEAR 和 CS 的值不同但它们仍然属于同一周期的DAS,因此属于一组。

所以,为了强调 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))]