0

这是我的数据样本,它位于矩阵中:

BLOCK  RUNTIME
101    50
101    20
101    -25
101    -40
101    35
101    45
202    25
202    -10
202    -35
202    40
202    50
202    30
202    -20
202    15
.
.
.
n

我尚未编写的代码的期望输出是这样的:

BLOCK  TIME_CHUNKS
101    70
101    -65
101    80
202    25
202    -45
202    120
202    -20
202    15

我希望代码做什么来获得输出:只要后续行的 BLOCK 值等于当前行的 BLOCK 值,并且只要后续行的 RUNTIME 值是相同的符号,对它们求和并填充具有 BLOCK 值和总和值的表中的新行。然后从你离开的地方继续。在示例数据中,前两行 (50, 20) 被求和并写入表中。然后 RUNTIME 的符号切换并在两行(-25,-40)中保持不变,因此将这些值相加。然后RUNTIME的符号再次切换,三行(35、45、25)为正,但是这三行的最后一行有不同的BLOCK编号,所以只有这三行的前两行相加并写入表. 继续直到到达矩阵的末尾。

制作条件语句对我来说很容易,但我不知道如何“跟踪”我在矩阵中的位置以重新启动求和过程。我对 for 或 while 循环不是那么精通,甚至无法对它们如何在这里使用做出有根据的猜测。我在编写函数时做了一次可怜的尝试,但没有成功。

需要自动化这个过程...我有大约 10,000 行数据,可以根据一组场景变量动态生成。每组变量都会生成一个表,其中包含不同的 RUNTIME 值,并且我有很多场景要运行。

非常感谢任何帮助。

4

2 回答 2

1
TIME_CHUNKS <- with(df, tapply(RUNTIME, BLOCK, function(x)
  tapply(x, cumsum(c(1, diff(sign(x)) != 0)), sum)))

out <- data.frame(BLOCK = rep.int(unique(df$BLOCK), sapply(TIME_CHUNKS, length)),
                  TIME_CHUNKS = unlist(TIME_CHUNKS), row.names = NULL)

例子

使用此数据并粘贴上面的代码

 df <- data.frame(BLOCK = c(101, 101, 101, 101, 101, 101, 202, 202,
 202, 202, 202, 202, 202, 202), RUNTIME = c(50, 20, -25, -40,
 35, 45, 25, -10, -35, 40, 50, 30, -20, 15))

你将out成为:

 BLOCK TIME_CHUNKS
   101          70
   101         -65
   101          80
   202          25
   202         -45
   202         120
   202         -20
   202          15

解释

注意嵌套使用tapply. 换句话说,上面的代码计算TIME_CHUNKS的是:

  1. 将每一行拆分为BLOCK, 并让x成为给定块的向量(例如, x将首先是c(50, 20, -25, -40, 35, 45).

  2. 奇怪的外观cumsum(c(1, diff(sign(x)) != 0))只是将我们的块细分为具有相同符号的数字的连续组。即,根据符号切换与否diff(sign(x)) != 0给出 TRUEs 和s 的向量,并强制转换为整数与产生一个向量,该向量为具有相同符号的每个子序列给出不同的数字。沿每个子序列应用总和给出我们正在寻找的结果。FALSEcumsum

于 2014-07-19T07:47:04.180 回答
0

使用dplyr. 用作@Robert dfKrzyzanowski 帖子中的数据集

library(dplyr)
 df%>%group_by(BLOCK)%>%
 mutate(n=n(), indx=cumsum(c(T, sign(RUNTIME[-1])!=sign(RUNTIME[-n])))) %>%
 group_by(BLOCK,indx) %>%
 summarize(TIME_CHUNKS=sum(RUNTIME)) %>%
 select(-indx)

 #      BLOCK TIME_CHUNKS
 #1   101          70
 #2   101         -65
 #3   101          80
 #4   202          25
 #5   202         -45
 #6   202         120
 #7   202         -20
 #8   202          15
于 2014-07-19T07:56:50.643 回答