2011-10-19 30 views
5

Giả sử bạn có một khung dữ liệu như thế này:Tính khoản tiền tích lũy của các giá trị nhất định

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 

và bạn muốn có một sản lượng như thế này:

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 

Các 4. yếu tố của cột Cum.sum là tổng của 1 và 2, phần tử 5. của cột Cum.sum là tổng của 2 và 3 và cứ thế ... Điều này có nghĩa, tôi muốn xây dựng tổng tích lũy của hàng đầu tiên và lưu nó ở hàng thứ hai. Tuy nhiên, tôi không muốn tổng tích lũy thông thường nhưng tổng của phần tử 2 hàng phía trên hàng hiện tại cộng với phần tử 3 hàng phía trên hàng hiện tại.

Tôi allready đã cố gắng để chơi một chút xung quanh với hàm tổng và cumsum nhưng tôi đã thất bại.

Bất kỳ ý tưởng nào?

Cảm ơn!

Trả lời

3

Bạn có thể sử dụng chức năng embed để tạo độ trễ thích hợp, rowSums để tổng hợp, sau đó tụt hậu một cách thích hợp (tôi đã sử dụng head).

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

Cảm ơn Joshua! Hoạt động tuyệt vời! –

0

Bạn không cần bất kỳ chức năng đặc biệt, chỉ cần sử dụng các hoạt động vector bình thường (các giải pháp này đều tương đương):

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

hoặc

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

hoặc

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

Tôi tin rằng 3 khoản tiền đầu tiên NÊN b e NA, không phải là 0, nhưng nếu bạn thích zero, bạn có thể khởi tạo các khoản tiền đầu tiên:

df$Cum.sums <- 0 
+0

Trong khi đây là giải pháp hợp lệ cho vấn đề cụ thể này, nó không khái quát hóa độc đáo (ví dụ: nếu tổng tích lũy vượt quá 20 hàng thay vì 2). –

+0

@Joshua, bạn nói đúng, tôi đã đăng giải pháp tổng quát hơn, nhưng không thực tế lắm. Giải pháp của bạn có lẽ sẽ là tốt nhất. – TMS

0

Một giải pháp, thanh lịch và nói chung, sử dụng phép nhân ma trận - và vì vậy rất không hiệu quả đối với dữ liệu lớn. Vì vậy, nó không thực tế nhiều, mặc dù một bài tập tốt đẹp:

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 
Các vấn đề liên quan