使用列的循环值对 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 并不是您所说的 YEAR
和 CS
的串联...如果这只是印刷错误,那么 Arun 的评论是正确的.如果不是,那么您可能需要重述,因为 Arun 的回答会给出意想不到的结果。
试试下面的方法,还没计时。 ifelse 可能不会尽可能快,但我能做到最好的快速时尚。如果它很慢让我知道,我们会重新散列它:
mydt[DAS == 1,GRP := .GRP, by = DAS][,GRP2 := cumsum(ifelse(is.na(GRP),0,GRP))]
我有一个每日数据集,需要根据一列的循环值进行分组。我想添加另一列包含分组标识符。比如我有这组数据
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 并不是您所说的 YEAR
和 CS
的串联...如果这只是印刷错误,那么 Arun 的评论是正确的.如果不是,那么您可能需要重述,因为 Arun 的回答会给出意想不到的结果。
试试下面的方法,还没计时。 ifelse 可能不会尽可能快,但我能做到最好的快速时尚。如果它很慢让我知道,我们会重新散列它:
mydt[DAS == 1,GRP := .GRP, by = DAS][,GRP2 := cumsum(ifelse(is.na(GRP),0,GRP))]