2013-11-28 45 views
2

我被困在一個相當簡單的數據管理任務中。我在R A交易數據幀類似於這樣:保留R中的前一個日期

id<-c(11,11,22,22,22) 
dates<-as.Date(c('2013-11-15','2013-11-16','2013-11-15','2013-11-16','2013-11-17'), "%Y-%m-%d") 
example<-data.frame(id=id,dates=dates) 

    id  dates 
1 11 2013-11-15 
2 11 2013-11-16 
3 22 2013-11-15 
4 22 2013-11-16 
5 22 2013-11-17 

我正在尋找一種方式來保留先前的交易日期。結果表是這樣的:

previous_dates<-as.Date(c('','2013-11-15','','2013-11-15','2013-11-16'), "%Y-%m-%d") 
example2<-data.frame(id=id,dates=dates, previous_dates=previous_dates) 

    id  dates previous_dates 
1 11 2013-11-15   <NA> 
2 11 2013-11-16  2013-11-15 
3 22 2013-11-15   <NA> 
4 22 2013-11-16  2013-11-15 
5 22 2013-11-17  2013-11-16 

我看着其他類似的問題,一個解決方案,這是非常接近我想要的是:

library(data.table) 
dt <- as.data.table(example) 

prev_date <- function(x) c(x[1],x) 

dt[,prev:=prev_date(dates), by=id] 

與這一個問題是,如果有是沒有以前的日期(像在ID = 11周的日期的情況下,2013年11月15日=)該函數將輸出導致相同日期:

id  dates previous_dates 
1 11 2013-11-15  2013-11-15 
2 11 2013-11-16  2013-11-15 

有人可以幫忙嗎?

回答

3
example$previous_dates <- ave(example$dates, example$id, 
       FUN= function(dt) c.Date(c(NA, dt[-length(dt)]) 
              )) 
> example 
    id  dates previous_dates 
1 11 2013-11-15   <NA> 
2 11 2013-11-16  2013-11-15 
3 22 2013-11-15   <NA> 
4 22 2013-11-16  2013-11-15 
5 22 2013-11-17  2013-11-16 

與Date對象的類玩弄....這也適用:

example$previous_dates <- ave(example$dates, example$id, 
      FUN= function(dt) structure( 
            c(NA, dt[-length(dt)]), 
            class="Date") ) 
+0

這一個也適用。謝謝迪文! –

+0

實際上,您的解決方案在應用於大型數據集時比Roland的工作速度更快。 –

+0

@NikolayNenov如果你的數據集非常大,並且有很多ID,你應該使用data.table。我只是沒有顯示如何去做,因爲我沒有找到解決方案來保存Date類,並且需要做一些類似於Dwin在他的答案的第一個修訂版中使用的內容。 – Roland

4
library(plyr) 
example <- ddply(example, .(id), transform, 
            previous_dates=c(as.Date(NA), head(dates, -1))) 
    id  dates previous_dates 
1 11 2013-11-15   <NA> 
2 11 2013-11-16  2013-11-15 
3 22 2013-11-15   <NA> 
4 22 2013-11-16  2013-11-15 
5 22 2013-11-17  2013-11-16 
+1

我喜歡的as.Date( NA)策略。我需要在c()刪除我的Date類後重新使用as.Date.numeric進行日期記錄。 –

+2

@DWin'c.Date(NA,head(dates,-1))'也可以。 – Roland

+0

那麼它的S3派遣現象呢?第一個論證勝出,NA「沒有階級」。 –

1

只是另一種方法:

transform(example, previous_dates = ave(dates, id, FUN = 
             function(x) x[c(NA, (seq_along(x)-1))])) 

    id  dates previous_dates 
1 11 2013-11-15   <NA> 
2 11 2013-11-16  2013-11-15 
3 22 2013-11-15   <NA> 
4 22 2013-11-16  2013-11-15 
5 22 2013-11-17  2013-11-16