12

我觉得这是一个相当简单的问题,但对于我的生活,我似乎无法找到答案。我有一个相当标准的数据框,我想做的是对一列值求和,直到它们达到某个值(该值或大于该值),此时它将 1 放入一个新列(标记为keep) 并在 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 放在保持列中,然后重新开始求和,并继续在整个数据集中运行。

提前致谢,如果您需要更多信息,请告诉我。

艾登

4

3 回答 3

11

我认为这最好用 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 所指出的,您的描述并不完全清楚。

于 2013-03-17T22:22:38.783 回答
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
于 2013-03-17T22:36:26.973 回答
2

我仍然不明白总和何时应该重新开始以及它是否应该为零。理想的结果将有很大帮助。

尽管如此,我不禁认为简单的索引和减法将是一种直接的方法。下面的代码给出了与@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]
于 2013-03-18T02:18:26.923 回答