2013-03-17 15 views
11

Bunun oldukça kolay bir soru olduğunu düşünüyorum, ancak yaşamın bir cevabı bulamıyorum. Oldukça standart bir veri çerçevem ​​var ve yapmaya çalıştığım şey, bir değer sütununa (ya tam değere ya da bundan büyük) ulaşana kadar bir değer sütunu toplamıdır. tutun) ve toplamı 0 olarak yeniden başlatır.Maksimum ulaşılana kadar toplamı toplayın, sonra bir sonraki satırda sıfırdan tekrarlayın

Dakikalar arasında bir sütunum var; dakikalar, bir bekletme sütunu ve birikimli bir toplam sütunu arasındaki farklar (kullandığım örnek gerçek tam veri kümesinden çok daha temizdir)

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 

fark toplam sütun kodu

caribou.sub$difference_sum<-cumsum(difference) 
hesaplandı

Ne yapmak isterim ki, toplanan değer 1470'e ulaştığında veya daha sonra herhangi bir sayı daha büyükse veya daha sonra herhangi bir sayıya ulaştığında yukarıdaki kodu çalıştırmanız gerekir. Veri kümesi.

Şimdiden teşekkürler, ve daha fazla bilgiye ihtiyacınız olursa lütfen bildirin.

Ayden

+3

1470'e ulaşıldığında 'difference_sum' sıfırlandı mı? "Difference_sum" eşiği geçtiğinde dahil olmak üzere biraz daha uzun bir örnek kümesi yardımcı olacaktır. – alexwhan

+0

Hayır, yapmaya çalıştığım şey şu, fark toplamı sütunu şu anda caribou.sub $ difference_sum <-cumsum (fark) koduyla hesaplanıyor. Sadece veri kümesinde ilerlemeye devam ediyor. – HeidelbergSlide

+0

Tamam, ancak eşiği geçtikten sonra, bir sonraki eşiği hesaplamaya nasıl başlıyorsunuz? Fazlalığı 1470'in üzerinde kullanıyor musunuz yoksa bir sonraki satırdan 0'dan başlıyor musunuz? – alexwhan

cevap

7

Ben kutunun dışında bu yüzden yapabileceği bir fonksiyonun düşünemiyorum, bu döngü için yapılır iyi olduğunu düşünüyorum. İstediğinizi yapmalısınız (eğer sizi doğru anlıyorsam).

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 
    } 
} 

Tam olarak ne isterseniz, yorum yapmaktan çekinmeyin. Ama AlexWhan'ın işaret ettiği gibi, açıklamanız tamamen açık değil.

+0

Ah, mükemmel, evet, aynen öyle. Yapmam gereken tek şey kopyalayıp yapıştırmak ve oradaydı. Çok teşekkürler. – HeidelbergSlide

+0

İlk satır 180 olsa. 0 olmalı mı? – Aaron

+0

Örnekte? 0 olmalı, ben bunu değiştirdim. – HeidelbergSlide

7

Şu Verilerinizi varsayarsak data.framedf geçerli:

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

Bu, tam olarak nereye gittiğ[email protected] - bu, – alexwhan

+0

no "sıfırdan tekrar et" döngüsünden belirgin şekilde daha hızlı olacaktır. Diğer cevaptan ayrılacak. –

+0

@MatthewLundberg, yani op cumsum de sağ cumsum değerleri ile ilgileniyor? Sadece "tutmak" olduğunu düşündüm? – Arun

1

o zaman sıfır olmalıdır eğer hala toplamı yeniden gerekirken hakkında anlamak ve yok. İstenen sonuç büyük ölçüde yardımcı olacaktır. Bununla birlikte, yardım edemiyorum ama sadece indeksleme ve çıkarma işleminin bunu yapmanın basit bir yolu olacağını düşünmüyorum. Aşağıdaki kod, @ Henrik'in çözümü ile aynı sonucu verir.

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] 
+0

Bu gerçekten yakın, ama (bunu anladığım kadarıyla ve çok yanlış olabilir) çünkü bir önceki seçimdeki fazlalık sütununun cumsumunu bir sonraki seçime dahil ediyorsunuz. yakında (ilk seçilen değer 1620 dakikadır, ancak bu değer yok sayılması gereken 150 dakika bırakır ancak sonraki seçim için kullanılır, böylece sonraki seçim 1440'ta gerçekleşir (çünkü cumsum gerçekte 150 dakikadan fazla olduğunu söyler)) . bu mantıklı mı? Yardımın için teşekkürler! – HeidelbergSlide

+0

Oh, anlıyorum. Evet, bence bu doğru (cevabımın doğru olmadığı anlamına geliyor). Yine, istediğiniz çıktıya sahip daha büyük bir örnek çok yararlı olacaktır, ancak sorun çözüldüğüne benziyorsa, bu noktada rahatsızlığa değmeyebilir. – Aaron

İlgili konular