Подтвердить что ты не робот

Суммарная сумма до достижения максимума, затем повторите с нуля в следующей строке

Я чувствую, что это довольно простой вопрос, но для жизни меня я не могу найти ответ. У меня довольно стандартный фреймворк данных, и то, что я пытаюсь сделать, это суммирование столбца значений до тех пор, пока они не достигнут некоторого значения (либо точного значения, либо больше его), после чего он упадет 1 в новый столбец (помечен сохранить) и перезапустить суммирование в 0.

У меня есть столбец минут, разница между минутами, столбец keep и столбец общей суммы (пример, который я использую, намного чище, чем фактический полный набор данных)

 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 в колонку сохранения и затем перезапускает суммирование впоследствии и продолжает работать в течение набор данных.

Спасибо заранее, и если вам нужна дополнительная информация, дайте мне знать.

Айден

4b9b3361

Ответ 1

Я думаю, что это лучше всего сделать с циклом 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, ваше описание не совсем ясно.

Ответ 2

Предполагая, что ваш data.frame равен df:

df$difference_sum <- c(0, head(cumsum(df$difference), -1))
# get length of 0 (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

Ответ 3

Я все еще не понимаю, когда сумма должна перезапуститься, и если она будет равна нулю. Желаемый результат очень помог.

Тем не менее, я не могу не думать, что просто индексирование и вычитание были бы простым способом сделать это. Код ниже дает тот же результат, что и решение @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]