R:求和到0再重新开始
R: Sum until 0 is reached and then restart
补充一下已经说过或评论过的内容 post:Cumulative sum until maximum reached, then repeat from zero in the next row
我有一个类似的数据框,其中包含大约 50k+ 个观察值。这个数据框是从一个 csv 文件中读取的,是已经对其执行的几个操作的结果。在此处粘贴示例:
Home Date Time Appliance Run value
679 2 1/21/2017 1:30:00 0 1 0
680 2 1/21/2017 1:45:00 0 1 0
681 2 1/21/2017 2:00:00 0 1 0
682 2 1/21/2017 2:15:00 0 1 0
683 2 1/21/2017 2:30:00 804 0 1
684 2 1/21/2017 2:45:00 556 0 804
685 2 1/21/2017 3:00:00 844 0 1360
686 2 1/21/2017 3:15:00 396 0 2204
687 2 1/21/2017 3:30:00 392 0 2600
688 2 1/21/2017 3:45:00 1220 0 2992
689 2 1/21/2017 4:00:00 0 1 0
690 2 1/21/2017 4:15:00 0 1 0
691 2 1/21/2017 4:30:00 0 1 0
692 2 1/21/2017 4:45:00 0 1 0
783 2 1/22/2017 3:30:00 0 1 0
784 2 1/22/2017 3:45:00 244 0 4212
785 2 1/22/2017 4:00:00 1068 0 4456
786 2 1/22/2017 4:15:00 44 0 5524
787 2 1/22/2017 4:30:00 1240 0 5568
788 2 1/22/2017 4:45:00 40 0 6808
789 2 1/22/2017 5:00:00 1608 0 6848
790 2 1/22/2017 5:15:00 0 1 0
791 2 1/22/2017 5:30:00 0 1 0
我使用的代码,作为答案之一给出,df = transform(df, value = ave(Appliance, Run, FUN = function(x)c(1, head(cumsum(x),-1))))
。
但是,正如您在输出中看到的那样,总和不会在下一次出现 0 时重新开始加上第一组(683-688 索引)的最后总和被转发到 784(索引号)。请帮助我在下次出现 0 时重新开始求和。
预期输出:
Home Date Time Appliance Run value
679 2 1/21/2017 1:30:00 0 1 0
680 2 1/21/2017 1:45:00 0 1 0
681 2 1/21/2017 2:00:00 0 1 0
682 2 1/21/2017 2:15:00 0 1 0
683 2 1/21/2017 2:30:00 804 0 804
684 2 1/21/2017 2:45:00 556 0 1360
685 2 1/21/2017 3:00:00 844 0 2204
686 2 1/21/2017 3:15:00 396 0 2600
687 2 1/21/2017 3:30:00 392 0 2992
688 2 1/21/2017 3:45:00 1220 0 4212
689 2 1/21/2017 4:00:00 0 1 0
690 2 1/21/2017 4:15:00 0 1 0
691 2 1/21/2017 4:30:00 0 1 0
692 2 1/21/2017 4:45:00 0 1 0
783 2 1/22/2017 3:30:00 0 1 0
784 2 1/22/2017 3:45:00 244 0 244
785 2 1/22/2017 4:00:00 1068 0 1312
786 2 1/22/2017 4:15:00 44 0 1356
787 2 1/22/2017 4:30:00 1240 0 2596
788 2 1/22/2017 4:45:00 40 0 2636
789 2 1/22/2017 5:00:00 1608 0 4244
790 2 1/22/2017 5:15:00 0 1 0
791 2 1/22/2017 5:30:00 0 1 0
P.S:我也试过了:
这里有一个data.table
选项。您的分组变量不应为 Run
,而应为 rleid(Run)
。
library(data.table)
dt <- fread(text)
dt[, value := cumsum(Appliance), by = rleid(Run)]
dt
# V1 Home Date Time Appliance Run value
# 1: 679 2 1/21/2017 1:30:00 0 1 0
# 2: 680 2 1/21/2017 1:45:00 0 1 0
# 3: 681 2 1/21/2017 2:00:00 0 1 0
# 4: 682 2 1/21/2017 2:15:00 0 1 0
# 5: 683 2 1/21/2017 2:30:00 804 0 804
# 6: 684 2 1/21/2017 2:45:00 556 0 1360
# 7: 685 2 1/21/2017 3:00:00 844 0 2204
# 8: 686 2 1/21/2017 3:15:00 396 0 2600
# 9: 687 2 1/21/2017 3:30:00 392 0 2992
#10: 688 2 1/21/2017 3:45:00 1220 0 4212
#11: 689 2 1/21/2017 4:00:00 0 1 0
#12: 690 2 1/21/2017 4:15:00 0 1 0
#13: 691 2 1/21/2017 4:30:00 0 1 0
#14: 692 2 1/21/2017 4:45:00 0 1 0
#15: 783 2 1/22/2017 3:30:00 0 1 0
#16: 784 2 1/22/2017 3:45:00 244 0 244
#17: 785 2 1/22/2017 4:00:00 1068 0 1312
#18: 786 2 1/22/2017 4:15:00 44 0 1356
#19: 787 2 1/22/2017 4:30:00 1240 0 2596
#20: 788 2 1/22/2017 4:45:00 40 0 2636
#21: 789 2 1/22/2017 5:00:00 1608 0 4244
#22: 790 2 1/22/2017 5:15:00 0 1 0
#23: 791 2 1/22/2017 5:30:00 0 1 0
#24: 792 2 1/22/2017 5:45:00 0 1 0
#25: 793 2 1/22/2017 6:00:00 0 1 0
#26: 794 2 1/22/2017 6:15:00 0 1 0
#27: 795 2 1/22/2017 6:30:00 0 1 0
#28: 796 2 1/22/2017 6:45:00 0 1 0
#29: 797 2 1/22/2017 7:00:00 0 1 0
#30: 798 2 1/22/2017 7:15:00 0 1 0
在base R
我们可以做到
df1 <- read.table(text = text, stringsAsFactors = FALSE, header = TRUE)
rle_Run <- rle(df1$Run)
df1$value <- with(df1, ave(Appliance, rep(seq_along(rle_Run$lengths), rle_Run$lengths), FUN = cumsum))
数据
text <- " Home Date Time Appliance Run value
679 2 1/21/2017 1:30:00 0 1 0
680 2 1/21/2017 1:45:00 0 1 0
681 2 1/21/2017 2:00:00 0 1 0
682 2 1/21/2017 2:15:00 0 1 0
683 2 1/21/2017 2:30:00 804 0 1
684 2 1/21/2017 2:45:00 556 0 804
685 2 1/21/2017 3:00:00 844 0 1360
686 2 1/21/2017 3:15:00 396 0 2204
687 2 1/21/2017 3:30:00 392 0 2600
688 2 1/21/2017 3:45:00 1220 0 2992
689 2 1/21/2017 4:00:00 0 1 0
690 2 1/21/2017 4:15:00 0 1 0
691 2 1/21/2017 4:30:00 0 1 0
692 2 1/21/2017 4:45:00 0 1 0
783 2 1/22/2017 3:30:00 0 1 0
784 2 1/22/2017 3:45:00 244 0 4212
785 2 1/22/2017 4:00:00 1068 0 4456
786 2 1/22/2017 4:15:00 44 0 5524
787 2 1/22/2017 4:30:00 1240 0 5568
788 2 1/22/2017 4:45:00 40 0 6808
789 2 1/22/2017 5:00:00 1608 0 6848
790 2 1/22/2017 5:15:00 0 1 0
791 2 1/22/2017 5:30:00 0 1 0
792 2 1/22/2017 5:45:00 0 1 0
793 2 1/22/2017 6:00:00 0 1 0
794 2 1/22/2017 6:15:00 0 1 0
795 2 1/22/2017 6:30:00 0 1 0
796 2 1/22/2017 6:45:00 0 1 0
797 2 1/22/2017 7:00:00 0 1 0
798 2 1/22/2017 7:15:00 0 1 0"
补充一下已经说过或评论过的内容 post:Cumulative sum until maximum reached, then repeat from zero in the next row
我有一个类似的数据框,其中包含大约 50k+ 个观察值。这个数据框是从一个 csv 文件中读取的,是已经对其执行的几个操作的结果。在此处粘贴示例:
Home Date Time Appliance Run value
679 2 1/21/2017 1:30:00 0 1 0
680 2 1/21/2017 1:45:00 0 1 0
681 2 1/21/2017 2:00:00 0 1 0
682 2 1/21/2017 2:15:00 0 1 0
683 2 1/21/2017 2:30:00 804 0 1
684 2 1/21/2017 2:45:00 556 0 804
685 2 1/21/2017 3:00:00 844 0 1360
686 2 1/21/2017 3:15:00 396 0 2204
687 2 1/21/2017 3:30:00 392 0 2600
688 2 1/21/2017 3:45:00 1220 0 2992
689 2 1/21/2017 4:00:00 0 1 0
690 2 1/21/2017 4:15:00 0 1 0
691 2 1/21/2017 4:30:00 0 1 0
692 2 1/21/2017 4:45:00 0 1 0
783 2 1/22/2017 3:30:00 0 1 0
784 2 1/22/2017 3:45:00 244 0 4212
785 2 1/22/2017 4:00:00 1068 0 4456
786 2 1/22/2017 4:15:00 44 0 5524
787 2 1/22/2017 4:30:00 1240 0 5568
788 2 1/22/2017 4:45:00 40 0 6808
789 2 1/22/2017 5:00:00 1608 0 6848
790 2 1/22/2017 5:15:00 0 1 0
791 2 1/22/2017 5:30:00 0 1 0
我使用的代码,作为答案之一给出,df = transform(df, value = ave(Appliance, Run, FUN = function(x)c(1, head(cumsum(x),-1))))
。
但是,正如您在输出中看到的那样,总和不会在下一次出现 0 时重新开始加上第一组(683-688 索引)的最后总和被转发到 784(索引号)。请帮助我在下次出现 0 时重新开始求和。
预期输出:
Home Date Time Appliance Run value
679 2 1/21/2017 1:30:00 0 1 0
680 2 1/21/2017 1:45:00 0 1 0
681 2 1/21/2017 2:00:00 0 1 0
682 2 1/21/2017 2:15:00 0 1 0
683 2 1/21/2017 2:30:00 804 0 804
684 2 1/21/2017 2:45:00 556 0 1360
685 2 1/21/2017 3:00:00 844 0 2204
686 2 1/21/2017 3:15:00 396 0 2600
687 2 1/21/2017 3:30:00 392 0 2992
688 2 1/21/2017 3:45:00 1220 0 4212
689 2 1/21/2017 4:00:00 0 1 0
690 2 1/21/2017 4:15:00 0 1 0
691 2 1/21/2017 4:30:00 0 1 0
692 2 1/21/2017 4:45:00 0 1 0
783 2 1/22/2017 3:30:00 0 1 0
784 2 1/22/2017 3:45:00 244 0 244
785 2 1/22/2017 4:00:00 1068 0 1312
786 2 1/22/2017 4:15:00 44 0 1356
787 2 1/22/2017 4:30:00 1240 0 2596
788 2 1/22/2017 4:45:00 40 0 2636
789 2 1/22/2017 5:00:00 1608 0 4244
790 2 1/22/2017 5:15:00 0 1 0
791 2 1/22/2017 5:30:00 0 1 0
P.S:我也试过了:
这里有一个data.table
选项。您的分组变量不应为 Run
,而应为 rleid(Run)
。
library(data.table)
dt <- fread(text)
dt[, value := cumsum(Appliance), by = rleid(Run)]
dt
# V1 Home Date Time Appliance Run value
# 1: 679 2 1/21/2017 1:30:00 0 1 0
# 2: 680 2 1/21/2017 1:45:00 0 1 0
# 3: 681 2 1/21/2017 2:00:00 0 1 0
# 4: 682 2 1/21/2017 2:15:00 0 1 0
# 5: 683 2 1/21/2017 2:30:00 804 0 804
# 6: 684 2 1/21/2017 2:45:00 556 0 1360
# 7: 685 2 1/21/2017 3:00:00 844 0 2204
# 8: 686 2 1/21/2017 3:15:00 396 0 2600
# 9: 687 2 1/21/2017 3:30:00 392 0 2992
#10: 688 2 1/21/2017 3:45:00 1220 0 4212
#11: 689 2 1/21/2017 4:00:00 0 1 0
#12: 690 2 1/21/2017 4:15:00 0 1 0
#13: 691 2 1/21/2017 4:30:00 0 1 0
#14: 692 2 1/21/2017 4:45:00 0 1 0
#15: 783 2 1/22/2017 3:30:00 0 1 0
#16: 784 2 1/22/2017 3:45:00 244 0 244
#17: 785 2 1/22/2017 4:00:00 1068 0 1312
#18: 786 2 1/22/2017 4:15:00 44 0 1356
#19: 787 2 1/22/2017 4:30:00 1240 0 2596
#20: 788 2 1/22/2017 4:45:00 40 0 2636
#21: 789 2 1/22/2017 5:00:00 1608 0 4244
#22: 790 2 1/22/2017 5:15:00 0 1 0
#23: 791 2 1/22/2017 5:30:00 0 1 0
#24: 792 2 1/22/2017 5:45:00 0 1 0
#25: 793 2 1/22/2017 6:00:00 0 1 0
#26: 794 2 1/22/2017 6:15:00 0 1 0
#27: 795 2 1/22/2017 6:30:00 0 1 0
#28: 796 2 1/22/2017 6:45:00 0 1 0
#29: 797 2 1/22/2017 7:00:00 0 1 0
#30: 798 2 1/22/2017 7:15:00 0 1 0
在base R
我们可以做到
df1 <- read.table(text = text, stringsAsFactors = FALSE, header = TRUE)
rle_Run <- rle(df1$Run)
df1$value <- with(df1, ave(Appliance, rep(seq_along(rle_Run$lengths), rle_Run$lengths), FUN = cumsum))
数据
text <- " Home Date Time Appliance Run value
679 2 1/21/2017 1:30:00 0 1 0
680 2 1/21/2017 1:45:00 0 1 0
681 2 1/21/2017 2:00:00 0 1 0
682 2 1/21/2017 2:15:00 0 1 0
683 2 1/21/2017 2:30:00 804 0 1
684 2 1/21/2017 2:45:00 556 0 804
685 2 1/21/2017 3:00:00 844 0 1360
686 2 1/21/2017 3:15:00 396 0 2204
687 2 1/21/2017 3:30:00 392 0 2600
688 2 1/21/2017 3:45:00 1220 0 2992
689 2 1/21/2017 4:00:00 0 1 0
690 2 1/21/2017 4:15:00 0 1 0
691 2 1/21/2017 4:30:00 0 1 0
692 2 1/21/2017 4:45:00 0 1 0
783 2 1/22/2017 3:30:00 0 1 0
784 2 1/22/2017 3:45:00 244 0 4212
785 2 1/22/2017 4:00:00 1068 0 4456
786 2 1/22/2017 4:15:00 44 0 5524
787 2 1/22/2017 4:30:00 1240 0 5568
788 2 1/22/2017 4:45:00 40 0 6808
789 2 1/22/2017 5:00:00 1608 0 6848
790 2 1/22/2017 5:15:00 0 1 0
791 2 1/22/2017 5:30:00 0 1 0
792 2 1/22/2017 5:45:00 0 1 0
793 2 1/22/2017 6:00:00 0 1 0
794 2 1/22/2017 6:15:00 0 1 0
795 2 1/22/2017 6:30:00 0 1 0
796 2 1/22/2017 6:45:00 0 1 0
797 2 1/22/2017 7:00:00 0 1 0
798 2 1/22/2017 7:15:00 0 1 0"