2015-10-16 75 views
2

我正在處理包含大約400個獨特主題的數據集。對於這個例子,我只會和兩個人一起工作。您可以使用此代碼生成的樣本數據:R dplyr選擇兩個單獨事件之間的最小日期差異行

set.seed(100) 
library(tidyr) 
library(dplyr) 
Subject<-c("A","A","A","A","A","A","B","B","B","B") 
Event1<-c("01/01/2001","01/01/2001","01/01/2001","01/01/2001","09/09/2001","09/09/2001","09/09/2009","09/09/2009","09/09/2009","09/09/2009") 

random.dates<-function(N,sd="2001-01-01",ed="2010-01-01"){ 
    sd<-as.Date(sd,"%Y-%m-%d") 
    ed<-as.Date(ed,"%Y-%m-%d") 
    dt<-as.numeric(difftime(ed,sd)) 
    ev<-sort(runif(N,0,dt)) 
    rt<-sd+ev 
} 
Event1<-as.Date(Event1,"%m/%d/%Y") 
Event1 
Event2<-print(random.dates(10)) 

df<-data.frame(Subject,Event1,Event2) 
df 

,併產生了接近此輸出輸出:

Subject  Event1  Event2 
1  A 2001-01-01 2001-05-04 
2  A 2001-01-01 2001-09-24 
3  A 2001-01-01 2002-10-22 
4  A 2001-01-01 2003-02-25 
5  A 2001-09-09 2007-07-16 
6  A 2001-09-09 2008-04-06 
7  B 2009-09-09 2008-07-12 
8  B 2009-09-09 2008-07-24 
9  B 2009-09-09 2009-04-01 
10  B 2009-09-09 2009-09-11 

在這種情況下,我很感興趣,具有獨特的事件1的第一組獨特的主題,我可以輕鬆做到。從那裏我需要選擇最接近事件1的事件2,這個獨特的主體事件1組合,我真的需要幫助。在這個例子中,這些數據應分解爲3個不同的記錄:

Subject  Event1  Event2 
1  A 2001-01-01 2001-05-04 
2  A 2001-09-09 2008-04-06 
3  B 2009-09-09 2009-09-11 

我傑裏 - 操縱的解決方案產生3條記錄主題事件1組合:

df2<-df 
df2$SubEv<-paste(df2$Subject,df2$Event1) 
df2$Event1<-NULL 
df2$Subject<-NULL 
df2$Event2<-NULL 
df2<-unique(df2) 
df2<-separate(df2,SubEv,c("Subject","Event1"),sep=" ") 

從這裏我剛剛失去了如何讓R從最接近Event1的Event2的日期中選擇d。

我已經知道我的代碼超效率和馬虎(可能是因爲我的方法在開始)。我想知道如何做到這一點(誠實地說),如果有辦法,我可以調用少於10行的代碼,這將是非常好的老闆。

+3

我想你正在尋找(使用dplyr):'df%>%group_by(Subject,Event1)%>%slice(which.min(abs(Event1 - Event2)))',但我不看到相同的三個Event2。 – Frank

+0

熱潮!做得好,@Frank。我不知道你可以將兩個不同的向量放入group_by,我也不知道切片。非常感謝! –

+1

哦,我明白了爲什麼:即使你設置了種子,我的'df'與你的不同,也許你可以重新運行你的代碼來驗證你打印在那裏的'df'。 – Frank

回答

5

隨着dplyr:

library(dplyr) 
df %>% 
    group_by(Subject, Event1) %>% 
    slice(which.min(abs(Event1 - Event2))) 
# Subject  Event1  Event2 
#  (chr)  (date)  (date) 
# 1  A 2001-01-01 2001-07-05 
# 2  A 2001-09-09 2004-05-02 
# 3  B 2009-09-09 2008-04-24 

評論:

group_by可以與多個列的工作。

slice選擇組內的行號。或者......

... %>% filter(row_number() == which.min(abs(Event1 - Event2))) 

打領帶,which.min將返回第一個min。詳情請參閱?which.min


數據:當我運行了OP的代碼,我得到df看起來像

Subject  Event1  Event2 
1  A 2001-01-01 2001-07-05 
2  A 2001-01-01 2002-07-14 
3  A 2001-01-01 2003-04-27 
4  A 2001-01-01 2003-10-09 
5  A 2001-09-09 2004-05-02 
6  A 2001-09-09 2005-03-21 
7  B 2009-09-09 2005-05-10 
8  B 2009-09-09 2005-12-02 
9  B 2009-09-09 2005-12-21 
10  B 2009-09-09 2008-04-24 

這也解釋了爲什麼我的結果不完全匹配的OP的預期的結果。