2014-04-17 37 views
3

假設我有一個數據幀等類如何捕捉第一個事件的時間?

set.seed(123) 
df<-data.frame(id=rep(LETTERS[1:3],each=4), 
       days=as.integer(rnorm(12,100,10)), 
       event=rbinom(12,1,0.3)) 
df<-df[with(df,order(id,days)),] 
df$event[sample(3,1:12,T)]<-NA 
df[2,3]<-0 
df 
    id days event 
1 A 94  0 
2 A 97  0 
4 A 100 NA 
3 A 115  0 
8 B 87  1 
5 B 101  0 
7 B 104  1 
6 B 117  0 
9 C 93  0 
10 C 95  1 
12 C 103  0 
11 C 112  0 

我怎麼能忽略來港拍攝daysevent=1,如果沒有事件,然後返回最大天這樣的:

df2 
    id days event 
3 A 115  0 
8 B 87  1 
10 C 95  1 

回答

1

像這樣的問題,通常最好將它們分成更小的塊。首先,我們需要一個函數來爲給定的ID選擇正確的事件。因此,像:

get_index = function(event) { 
    test = (event==1) 
    if(sum(test, na.rm=TRUE)) 
    return(which.max(event)) 
    else 
    return(max(which(!test))) 
} 

和快速完整性檢查:

R> event = c(0, 0, NA, 0) 
R> get_index(event) 
[1] 4 
R> event = c(0, 1, 0, 0) 
R> get_index(event) 
[1] 2 

接下來,我們的數據增長ID分裂和應用功能,因此

R> library(plyr) 
R> ddply(df, .(id), summarize, 
        days = days[get_index(event)], 
        event=event[get_index(event)]) 
    id days event 
1 A 115  0 
2 B 87  1 
3 C 95  1 

我們可以做這麼多更高效(我們打電話get_index兩次),但這應該讓你開始。

4

這被擠壓成一條線,並使用data.table

require(data.table) ## >= 1.9.2 
setDT(df)[, min(days[event==1], max(days), na.rm=TRUE), by=id] 

它的工作原理的要求,但我還是建議你把它分解爲兩個(事件遭遇,並沒有遇到事件),併合並表。這依賴於在min()給定長度爲0的矢量,當在這種情況下max(days)踢返回Inf

setDT通過引用data.framedata.table轉換。