【发布时间】:2026-01-06 10:45:01
【问题描述】:
data.table 实现 asof(也称为 rolling 或 LOCF)开箱即用。我发现了这个相关的问题:
Filling in missing (blanks) in a data table, per category - backwards and forwards
但该问题的数据中有 NA。就我而言,我遵循那里的建议以保持数据不规则并使用roll=TRUE 加入它。我想做的不是将最后一个观察结果向前推进,而是尽可能有效地向后进行下一个观察。
这是我尝试过的,首先使用time:=-time 尝试欺骗它。我可以做得更好吗?我可以做得更快吗?
llorJoin <- function(A,B){
B <- copy(B);
keys <- key(A);
if( !identical(key(A), key(B)) | is.null(keys) ){
stop("llorJoin::ERROR; A and B should have the same non-empty keys");
}
lastKey <- tail(keys,1L);
myStr <- parse(text=paste0(lastKey,":=-as.numeric(",lastKey,")"));
A <- A[,eval(myStr)]; setkeyv(A,keys);
B <- B[,eval(myStr)]; setkeyv(B,keys);
origin <- "1970-01-01 00:00.00 UTC";
A <- B[A,roll=T];
myStr2 <- parse(text=paste0(lastKey,":=as.POSIXct(-",lastKey,",origin=origin)"));
A <- A[,eval(myStr2)]; setkeyv(A,keys);
return(A);
}
library(data.table)
A <- data.table(time=as.POSIXct(c("10:01:01","10:01:02","10:01:04","10:01:05","10:01:02","10:01:01","10:01:01"),format="%H:%M:%S"),
b=c("a","a","a","a","b","c","c"),
d=c(1,1.9,2,1.8,5,4.1,4.2));
B <- data.table(time=as.POSIXct(c("10:01:01","10:01:03","10:01:00","10:01:01"),format="%H:%M:%S"),b=c("a","a","c","d"), e=c(1L,2L,3L,4L));
setkey(A,b,time)
setkey(B,b,time)
library(rbenchmark)
benchmark(llorJoin(A,B),B[A,roll=T],replications=10)
test replications elapsed relative user.self sys.self user.child sys.child
1 llorJoin(A, B) 10 0.045 1 0.048 0 0 0
2 B[A, roll = T] 10 0.009 1 0.008 0 0 0
b time e d
1: a 2013-01-12 09:01:01 1 1.0
2: a 2013-01-12 09:01:02 2 1.9
3: a 2013-01-12 09:01:04 NA 2.0
4: a 2013-01-12 09:01:05 NA 1.8
5: b 2013-01-12 09:01:02 NA 5.0
6: c 2013-01-12 09:01:01 NA 4.1
7: c 2013-01-12 09:01:01 NA 4.2
因此,作为比较,初始数据上的 asof 连接要快 5 倍。
【问题讨论】:
-
您的问题具体是什么?你说你想要最后一次观察而不是
locf,但你已经有了一个实现。它有效吗?是不是太慢了?你在寻找更惯用的东西吗?我对data.table包一无所知,所以无论如何我都帮不上忙,但是对于您当前形式的问题,那些确实使用data.table的潜在回答者可能和我一样困惑。 -
问题是
B[A,roll=T]、A和B必须排序。然后反转time:=-time会破坏排序。我试图争取时间删除setkey排序,然后按A[,time:=time[.N:.1],by="b"]对“我自己”进行排序并使用setattr(A,c("b","time")),但它似乎更长......
标签: r join data.table