2014-02-17 116 views
3

我有這個表格,其中包含各種日期和相應的值,以下是每個日期的示例。在日期範圍內移動總和

Date  Value 
6/01/2013 8 
6/02/2013 4 
6/03/2013 1 
6/04/2013 7 
6/05/2013 1 
6/06/2013 1 
6/07/2013 3 
6/08/2013 8 
6/09/2013 4 
6/10/2013 2 
6/11/2013 10 
6/12/2013 4 
6/13/2013 7 
6/14/2013 3 
6/15/2013 2 
6/16/2013 1 
6/17/2013 7 
6/18/2013 5 
6/19/2013 1 
6/20/2013 4 

我所要做的是創建一個查詢,將創建一個新的列會顯示該值的列的總和指定日期範圍。例如,在下面,總和列包含其相應日期的總和,返回整整一週。所以2013年6月9日的總和將是2013年6月3日至2013年9月6日的總和。

Date  Sum 
6/01/2013 8 
6/02/2013 12 
6/03/2013 13 
6/04/2013 20 
6/05/2013 21 
6/06/2013 22 
6/07/2013 25 
6/08/2013 25 
6/09/2013 25 
6/10/2013 26 
6/11/2013 29 
6/12/2013 32 
6/13/2013 38 
6/14/2013 38 
6/15/2013 32 
6/16/2013 29 
6/17/2013 34 
6/18/2013 29 
6/19/2013 26 
6/20/2013 23 

我試過使用LIMIT子句,但我不能得到它的工作,任何幫助將不勝感激。

+1

我正在嘗試與data.table完全相同。我可以「思考」,但我做不到。一個需要一個.SD來分塊每個運行周,但我需要改變每個行的i參數。讓我看看是否可以將data.table放入? – Farrel

+1

這是一個'''data.table'''解決方案http://stackoverflow.com/questions/24397299/rolling-sum-by-another-variable-in-r/24400600#24400600 –

回答

1

使用data.table

require(data.table) 

#Build some sample data 
data <- data.table(Date=1:20,Value=rpois(20,10)) 

#Build reference table 
Ref <- data[,list(Compare_Value=list(I(Value)),Compare_Date=list(I(Date)))] 

#Use lapply to get last seven days of value by id 
data[,Roll.Val := lapply(Date, function(x) { 
        d <- as.numeric(Ref$Compare_Date[[1]] - x) 
        sum((d <= 0 & d >= -7)*Ref$Compare_Value[[1]])})] 

head(data,10) 

    Date Value Roll.Val 
1: 1 14  14 
2: 2  7  21 
3: 3  9  30 
4: 4  5  35 
5: 5 10  45 
6: 6 10  55 
7: 7 15  70 
8: 8 14  84 
9: 9  8  78 
10: 10 12  83 

這裏是另一個解決方案如果有人感興趣:

library("devtools") 
install_github("boRingTrees","mgahan") 
require(boRingTrees) 
rollingByCalcs(data,dates="Date",target="Value",stat=sum,lower=0,upper=7) 
+0

另一種方式,似乎要快得多,描述在http://stackoverflow.com/a/27983553/2490497 – jangorecki

+0

好的工作!但另一個組件是內存使用。不知道這些如何比較。對於大數據集,這是一個關鍵點。我認爲這是有希望的。 –

0

這裏是做

> input <- read.table(text = "Date  Value 
+ 6/01/2013 8 
+ 6/02/2013 4 
+ 6/03/2013 1 
+ 6/04/2013 7 
+ 6/05/2013 1 
+ 6/06/2013 1 
+ 6/07/2013 3 
+ 6/08/2013 8 
+ 6/09/2013 4 
+ 6/10/2013 2 
+ 6/11/2013 10 
+ 6/12/2013 4 
+ 6/13/2013 7 
+ 6/14/2013 3 
+ 6/15/2013 2 
+ 6/16/2013 1 
+ 6/17/2013 7 
+ 6/18/2013 5 
+ 6/19/2013 1 
+ 6/20/2013 4 ", as.is = TRUE, header = TRUE) 
> input$Date <- as.Date(input$Date, format = "%m/%d/%Y") # convert Date 
> 
> # create a sequence that goes a week back from the current data 
> x <- data.frame(Date = seq(min(input$Date) - 6, max(input$Date), by = '1 day')) 
> 
> # merge 
> merged <- merge(input, x, all = TRUE) 
> 
> # replace NAs with zero 
> merged$Value[is.na(merged$Value)] <- 0L 
> 
> # use 'filter' for the running sum and delete first 6 
> input$Sum <- filter(merged$Value, rep(1, 7), sides = 1)[-(1:6)] 
> input 
     Date Value Sum 
1 2013-06-01  8 8 
2 2013-06-02  4 12 
3 2013-06-03  1 13 
4 2013-06-04  7 20 
5 2013-06-05  1 21 
6 2013-06-06  1 22 
7 2013-06-07  3 25 
8 2013-06-08  8 25 
9 2013-06-09  4 25 
10 2013-06-10  2 26 
11 2013-06-11 10 29 
12 2013-06-12  4 32 
13 2013-06-13  7 38 
14 2013-06-14  3 38 
15 2013-06-15  2 32 
16 2013-06-16  1 29 
17 2013-06-17  7 34 
18 2013-06-18  5 29 
19 2013-06-19  1 26 
20 2013-06-20  4 23 
> 
1

zoo具有的功能rollapply它可以做的一個方式,你需要的東西:

z <- zoo(x$Value, order.by=x$Date) 

rollapply(z, width = 7, FUN = sum, partial = TRUE, align = "right") 
## 2013-06-01                 8 
## 2013-06-02                 12 
## 2013-06-03                 13 
## 2013-06-04                 20 
## 2013-06-05                 21 
## 2013-06-06                 22 
## 2013-06-07                 25 
## 2013-06-08                 25 
## 2013-06-09                 25 
## 2013-06-10                 26 
## 2013-06-11                 29 
## 2013-06-12                 32 
## 2013-06-13                 38 
## 2013-06-14                 38 
## 2013-06-15                 32 
## 2013-06-16                 29 
## 2013-06-17                 34 
## 2013-06-18                 29 
## 2013-06-19                 26 
## 2013-06-20                 23 
+0

但是如果每一個一天沒有自己的一排?換句話說,有些日子可能沒有數據。或者如果有幾天有兩排會發生什麼?你的解決方案工作,因爲它需要最後7行,但它假設它表示一個時間範圍?有沒有辦法做到這一點,但通過計算時間範圍? – Farrel