在R中,多次检查多个值,如果满足条件则求和,跟踪位置,导出数据和重复

时间:2014-07-19 07:35:55

标签: r loops conditional sumifs step-through

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

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值,AND等于后续行' RUNTIME值是相同的符号,将它们相加,并使用BLOCK值和求和值填充表中的新行。然后继续你离开的地方。在示例数据中,前两行(50,20)被求和并写入表中。然后RUNTIME的符号切换并且对于两行(-25,-40)是恒定的,因此将这些值相加。然后RUNTIME的符号再次切换,并且对于三行(35,45,25)是正的,但是这三行中的最后一行具有不同的BLOCK编号,因此只有这三行中的前两行被求和并写入表中。继续进行直到矩阵结束。

我很容易做出条件陈述,但我不知道如何跟踪"跟踪"我在矩阵中重新开始求和过程的地方。我并不精通for或while循环,甚至不知道如何在这里使用它们。我在写一个函数时做了一个可怜的尝试,但没有到达任何地方。

需要自动执行此过程...我已经获得了大约10,000行数据,这些数据可以根据一组场景变量动态生成。每组变量都会为RUNTIME生成一个具有不同值的表,并且我有很多场景要运行。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分: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给出了一个向量     TRUEFALSE根据符号切换与否,并强制转换为整数     与cumsum组合产生一个向量,为每个子序列提供不同的数字     有相同的标志。在每个子序列中应用一个总和会得到我们正在寻找的结果。

答案 1 :(得分:0)

使用dplyr。使用df作为@Robert Krzyzanowski发布的数据集

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