计算行之间的差异比for循环更快?

Dav*_*ino 5 r

我有一个如下所示的数据集:

ID   |   DATE    | SCORE
-------------------------
123  |  1/15/10  |  10
123  |  1/1/10   |  15
124  |  3/5/10   |  20
124  |  1/5/10   |  30
...
Run Code Online (Sandbox Code Playgroud)

因此,要将上述代码段作为数据框加载,代码为:

id<-c(123,123,124,124)
date<-as.Date(c('2010-01-15','2010-01-01','2010-03-05','2010-01-05'))
score<-c(10,15,20,30)
data<-data.frame(id,date,score)
Run Code Online (Sandbox Code Playgroud)


我正在尝试添加一列来计算"自此ID的最后一次记录以来的天数".

现在我使用的FOR循环看起来像这样:

data$dayssincelast <- rep(NA, nrow(data))
for(i in 2:nrow(data)) {
  if(data$id[i] == data$id[i-1]) 
    data$dayssincelast[i] <- data$date[i] - data$date[i-1]
}
Run Code Online (Sandbox Code Playgroud)


有更快的方法吗?(我看了一下APPLY,但除了FOR循环之外,还无法找到解决方案.)

提前致谢!

nog*_*pes 5

如果您的日期在订单范围内,这应该有用id.

id<-c(123,123,124,124)
date<-as.Date(c('2010-01-15','2010-01-01','2010-03-05','2010-01-05'))
score<-c(10,15,20,30)
data<-data.frame(id,date,score)

data <- data[order(data$id,data$date),]
data$dayssincelast<-do.call(c,by(data$date,data$id,function(x) c(NA,diff(x))))
# Or, even more concisely
data$dayssincelast<-unlist(by(data$date,data$id,function(x) c(NA,diff(x))))
Run Code Online (Sandbox Code Playgroud)