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
因此,作为比较,加入初始数据的速度要快5倍。
答案 0 :(得分:4)
roll
参数可以执行 nocb 。更新此答案,以便#615可以关闭。
您也不需要再设置按键了。相反,您可以使用on=
参数(在v1.9.6
中实现)指定要加入的列。有了这两个功能,任务可以按如下方式完成:
require(data.table) # v1.9.6+
A[B, on=c("b", "time"), roll=-Inf]
# time b e d
# 1: 2015-10-11 10:01:01 a 1 1.0
# 2: 2015-10-11 10:01:02 a 2 1.9
# 3: 2015-10-11 10:01:04 a NA 2.0
# 4: 2015-10-11 10:01:05 a NA 1.8
# 5: 2015-10-11 10:01:02 b NA 5.0
# 6: 2015-10-11 10:01:01 c NA 4.1
# 7: 2015-10-11 10:01:01 c NA 4.2
就是这样。
如果不改变data.table
,你就会以最快的方式接近。之前提交了以下功能请求:
FR#2300 Add backwards and firstback to roll=TRUE
我在这个问题上添加了一个链接。您可以在R-Forge上搜索功能请求列表。在这种情况下,像“roll”,“forward”和“backwards”这样的词语都能找到它。您可能需要4或5次尝试搜索尝试以确认错误或功能请求尚未提交。
我可能更快地实现该功能请求(内部只需要几行)而不是尝试,并为您提供最快的解决方法。