我有一个日常数据集,需要根据一列的循环值进行分组。我希望添加另一个包含分组标识符的列。例如,我有这组数据
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的周期属于一个群体。
答案 0 :(得分:0)
所以,只是为了突出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))]