到达最大值的累积总和,然后在下一行从零开始重复

时间:2013-03-17 22:15:03

标签: r loops if-statement cumsum

我觉得这是一个相当容易的问题,但对于我的生活,我似乎无法找到答案。我有一个相当标准的数据框,我想要做的是将一列值相加,直到它们达到某个值(精确值或大于它),此时它将1放入一个新列(标记为保持)并在0处重新开始求和。

我有一列分钟,分钟,保留列和累积总和列之间的差异(我使用的示例比实际的完整数据集更清晰)

 minutes     difference     keep     difference_sum
 1052991158       0          0            0
 1052991338      180         0            180
 1052991518      180         0            360
 1052991698      180         0            540
 1052991878      180         0            720
 1052992058      180         0            900
 1052992238      180         0            1080
 1052992418      180         0            1260
 1052992598      180         0            1440
 1052992778      180         0            1620
 1052992958      180         0            1800

使用代码

计算差异总和列
caribou.sub$difference_sum<-cumsum(difference)

我想要做的是运行上面的代码,条件是,当总和值达到1470或任何大于它的数字时,它会在保留列中放置1,然后重新开始求和,并继续运行数据集。

提前致谢,如果您需要更多信息,请与我们联系。

艾登

3 个答案:

答案 0 :(得分:10)

我认为最好用for循环完成,不能想到一个可以开箱即用的功能。以下应该做你想要的(如果我理解正确的话)。

current.sum <- 0
for (c in 1:nrow(caribou.sub)) {
    current.sum <- current.sum + caribou.sub[c, "difference"]
    carribou.sub[c, "difference_sum"] <- current.sum
    if (current.sum >= 1470) {
        caribou.sub[c, "keep"] <- 1
        current.sum <- 0
    }
}

如果不完全符合您的要求,请随意发表评论。但正如alexwhan所指出的,你的描述并不完全清楚。

答案 1 :(得分:8)

假设您的data.framedf

df$difference_sum <- c(0, head(cumsum(df$difference), -1))
# get length of 0's (first keep value gives the actual length)
len <- sum(df$difference_sum %/% 1470 == 0)
df$keep <- (seq_len(nrow(df))-1) %/% len
df <- transform(df, difference_sum = ave(difference, keep, 
          FUN=function(x) c(0, head(cumsum(x), -1))))

#       minutes difference keep difference_sum
# 1  1052991158        180    0              0
# 2  1052991338        180    0            180
# 3  1052991518        180    0            360
# 4  1052991698        180    0            540
# 5  1052991878        180    0            720
# 6  1052992058        180    0            900
# 7  1052992238        180    0           1080
# 8  1052992418        180    0           1260
# 9  1052992598        180    0           1440
# 10 1052992778        180    1              0
# 11 1052992958        180    1            180

答案 2 :(得分:1)

我仍然不明白何时应该重新启动总和,然后它应该为零。期望的结果将有很大帮助。

尽管如此,我不禁想到简单的索引和减法将是一种直接的方式。下面的代码给出了与@ Henrik解决方案相同的结果。

df$difference_sum <- cumsum(df$difference)
step <- (df$difference_sum %/% 1470) + 1
k <- which(diff(step) > 0) + 1
df$keep <- 0
df$keep[k] <- 1
step[k] <- step[k] - 1
df$difference_sum <- df$difference_sum - c(0, df$difference_sum[k])[step]