在R中,多次检查多个值,如果满足条件,求和,跟踪位置,导出数据,然后重复
以下是我的数据样本,它位于矩阵中:在R中,多次检查多个值,如果满足条件,求和,跟踪位置,导出数据,然后重复,r,loops,conditional,sumifs,step-through,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 8
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
我希望代码做什么来获得输出:只要后续行的块值等于当前行的块值,并且只要后续行的运行时值是相同的符号,就将它们求和,并使用块值和求和值填充表中的新行。然后从你停下来的地方继续。在示例数据中,前两行(50、20)相加并写入表中。然后,运行时符号切换,两行(-25,-40)为常量,因此这些值相加。然后运行时符号再次切换,三行(35、45、25)为正,但这三行中的最后一行具有不同的块号,因此只有这三行中的前两行被求和并写入表中。继续,直到到达矩阵的末尾
对我来说,做条件语句很容易,但我不知道如何“跟踪”我在矩阵中的位置以重新开始求和过程。我不太熟悉for或while循环,甚至不知道如何在这里使用它们。我可怜地试图编写一个函数,但没有成功
需要自动化这个过程…我有大约10000行数据,可以根据一组场景变量动态生成。每一组变量将为运行时生成一个具有不同值的表,我有很多场景要运行
非常感谢您的帮助
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)
解释
注意tapply
的嵌套用法。换句话说,上面的代码计算时间块所做的是:
将每行按块
分割,并将x
作为给定块的向量(例如,
x
首先是c(50,20,-25,-40,35,45)
看起来很古怪的cumsum(c(1,diff(符号(x))!=0))
只是将我们的区块细分
分成相同有符号数的连续组。即,diff(sign(x))!=0
给出
TRUE
s和FALSE
s取决于符号切换与否,并强制转换为整数
与cumsum
组合产生一个向量,该向量为每个子序列提供不同的数字
使用相同的符号。沿每个子序列应用一个和可以得到我们想要的结果
使用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
太好了。我花了一点时间来考虑diff(符号(x)!=0位。如果您想再次提供帮助,我现在正试图找出如何根据块/运行时条件对矩阵中的第三列求和。(“无论何时计算求和的运行时值,也要计算不同列中相同行的和(并将它们写到同一个表中。))只需这样做:其他块非常感谢。正如你所知,我遇到了另一个问题,我需要根据符号变化的不止一个标准(使用另一列中的数据)分解总和.你的例子让我想到了一个方法,使我能够克服这个障碍。谢谢你!
BLOCK TIME_CHUNKS
101 70
101 -65
101 80
202 25
202 -45
202 120
202 -20
202 15
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