2011-10-19 11 views
5

Załóżmy, że masz ramki danych tak:Obliczanie sum pewnych wartości

df <- data.frame(Nums = c(1,2,3,4,5,6,7,8,9,10), Cum.sums = NA) 
> df 
    Nums Cum.sums 
1  1  NA 
2  2  NA 
3  3  NA 
4  4  NA 
5  5  NA 
6  6  NA 
7  7  NA 
8  8  NA 
9  9  NA 
10 10  NA 

i chcesz wyjście tak:

Nums Cum.sums 
1  1  0 
2  2  0 
3  3  0 
4  4  3 
5  5  5 
6  6  7 
7  7  9 
8  8  11 
9  9  13 
10 10  15 

4. Element kolumny Cum.sum jest sumą 1 i 2, 5. element kolumny Cum.sum to suma 2 i 3 i tak dalej ... Oznacza to, że chciałbym zbudować skumulowaną sumę pierwszego rzędu i zapisać go w drugim rzędzie. Nie chcę jednak normalnej sumy skumulowanej, ale sumy wierszy elementu 2 powyżej bieżącego wiersza plus wiersze elementu 3 powyżej bieżącego wiersza.

Próbowałem już trochę zagrać za pomocą funkcji sum i cumsum, ale mi się nie udało.

Wszelkie pomysły?

Dzięki!

Odpowiedz

3

Można użyć funkcji embed, aby utworzyć odpowiednie opóźnienia, rowSums do sumy, a następnie odpowiednio opóźnić (użyłem head).

df$Cum.sums[-(1:3)] <- head(rowSums(embed(df$Nums,2)),-2) 
+0

Dzięki Joshua! Działa świetnie! –

0

Nie potrzeba żadnych specjalnych funkcji, wystarczy użyć normalne operacje wektorowe (rozwiązania te są równoważne):

df$Cum.sums[-(1:3)] <- head(df$Nums, -3) + head(df$Nums[-1], -2) 

lub

with(df, Cum.sums[-(1:3)] <- head(Nums, -3) + head(Nums[-1], -2)) 

lub

df$Cum.sums[-(1:3)] <- df$Nums[1:(nrow(df)-3)] + df$Nums[2:(nrow(df)-2)] 

Wierzę, że pierwsze 3 sumy POWINNY b e NA, nie 0, ale jeśli wolisz zera, można zainicjować sum pierwszy:

df$Cum.sums <- 0 
+0

Chociaż jest to poprawne rozwiązanie tego konkretnego problemu, nie ładnie się generalizuje (np. Jeśli łączna suma wynosi ponad 20 wierszy zamiast 2). –

+0

@ Joshu, masz rację, opublikowałem bardziej ogólne rozwiązanie, ale niezbyt praktyczne. Twoje rozwiązanie prawdopodobnie będzie najlepsze. – TMS

0

Innym rozwiązaniem, elegancki i ogólne, używając mnożenia macierzy - a więc bardzo nieefektywne dla dużych danych. Nie jest to zbyt praktyczne, ale przyjemne ćwiczenie:

len <- nrow(df) 
sr <- 2 # number of rows to sum 
lag <- 3 
mat <- matrix(
      head(c(
       rep(0, lag * len), 
       rep(rep(1:0, c(sr, len - sr + 1)), len) 
       ), len * len), 
      nrow = 10, byrow = TRUE 
     ) 
mat %*% df$Nums 
Powiązane problemy