2014-07-25 28 views
0

末考慮形式馬克開始和團體

 seller buyer  month 
1: 50536344 61961225 1993-01-01 
2: 50536344 61961225 1993-02-01 
3: 50536344 61961225 1993-04-01 
4: 50536344 61961225 1993-05-01 
5: 50536344 61961225 1993-06-01 

data.table結構,在那裏我有(buyer, seller)雙隨着時間的推移。我想標記每一對的開始和結束。例如,我們看到從一月到二月有一對,三月沒有,一到四月到六月。因此,下面的將是所期望的輸出:

 seller buyer  month start end 
1: 50536344 61961225 1993-01-01 True False 
2: 50536344 61961225 1993-02-01 False True 
3: 50536344 61961225 1993-04-01 True False 
4: 50536344 61961225 1993-05-01 False False 
5: 50536344 61961225 1993-06-01 False True 

回答

2

假設month處於Date類(或類似地用於POSIXtIDateTime或其他類與diff方法),則可以使用diff函數做到這一點。

# sort data.table 
setkeyv(dt, c("seller", "buyer", "month")) 
# define start 
dt[, start := c(TRUE, diff(month) > 31), by = list(seller, buyer)] 
# define end 
dt[, end := c(diff(month) > 31, TRUE), by = list(seller, buyer)] 

編輯:@David Arenburg的建議:你當然可以一次性定義開始和結束。這應該稍微快一點,但我也覺得它更難讀。

dt[, ":=" (start = c(TRUE, diff(month) > 31), 
      end = c(diff(month) > 31, TRUE)), 
    by = list(seller, buyer)] 

EDIT2:發生了什麼事的一些更explonation:每對賣方和買方先觀察將永遠是一個商業關係的開始,所以start = c(TRUE, ...)。之後,如果且僅當時間差超過一個月(31天)時,進一步觀察業務關係纔會開始,所以diff(month) > 31。把這兩件事放在一起,你得到c(TRUE, diff(month) > 31)。 一個類似的邏輯適用於最後,你必須比較下一個觀察,而不是前一個觀察。

+0

爲什麼你需要假設'Date'類?只需使用'data.table'中的'IDateTime',即:'dt [,start:= c(TRUE,diff(as.IDate(month))> 31),by = list(seller,buyer)]; dt [,end:= c(diff(as.IDate(month))> 31,TRUE),by = list(seller,buyer)]' –

+0

@David Arenburg:當然,'IDateTime'也可以,日期類(使用「diff」方法)而不是「字符」或「因素」。 – shadow

+0

另外,爲什麼不能一氣呵成呢?結束= c(差異(as.IDate(月))> 31,TRUE)),by(由於.IDate(月))> =清單(賣方,買方)]'。 (在':='後面加上反引號)。除此之外(+1):) –