如何捕捉第一次活动的时间?

时间:2014-04-17 13:58:38

标签: r

假设我有一个数据框,如:

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

如何通过忽略NAs来捕获days到第一个event=1,如果没有事件,则返回最大天数:

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

2 个答案:

答案 0 :(得分:4)

这被挤压成一行并使用data.table

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

它按照要求工作,但我仍然建议您将其拆分为两个(遇到事件,没有遇到事件)并合并表。当给定长度为0的向量时,这依赖于min()返回Inf。在这种情况下max(days)开始。

setDT通过引用将data.frame转换为data.table

答案 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),但这应该让你开始。