2013-08-19 59 views
0

我需要的是以一种有效的方式完成一些智能na.fill/nomatch的完全外连接。我已经使用循环完成了它,但我想使用矩阵代数或data.table操作来加速此过程。R data.table合并/全外连接与基于公式的na.fill/nomatch基于公式

以下数据是库存未结订单信息的样本,在询问未结订单和未结订单的数据集之间执行完全外连接。数据集是问,B是出价。这两个数据集都存储原子顺序及其累计和。其任务是通过累计值将所有询价订单与出价订单进行匹配,反之亦然。 填充示例数据:

price = c(11.25,11.26,11.35,12.5,14.2) 
amount = c(1.2,0.4,2.75,6.5,15.2) 
A <- data.table(ask_price = price, ask_amount = amount, ask_cum_amount = cumsum(amount), cum_value = cumsum(price*amount), ask_avg_price = cumsum(price*amount)/cumsum(amount)) 
price = c(11.18,11.1,10.55,10.25,9.7) 
amount = c(0.15,0.6,10.2,3.5,12) 
B <- data.table(bid_price = price, bid_amount = amount, bid_cum_amount = cumsum(amount), cum_value = cumsum(price*amount), bid_avg_price = cumsum(price*amount)/cumsum(amount)) 

常规的全外连接,它的结果:

setkey(A, cum_value) 
setkey(B, cum_value) 
C <- merge(A,B,all=TRUE) 
print(C) 

na.fill/NOMATCH 公式,每一行(问或投标),其中cum_value不匹配(请记住,除cum_value以外的其他所有字段均与ask or bid相关):

avg_price["current NA"] <- cum_value["last non NA"]/cum_value["current NA"] * avg_price["last non NA"] + (1-cum_value["last non NA"]/cum_value["current NA"]) * price["next non NA"] 
cum_amount["current NA"] <- cum_value["current NA"]/avg_price["current NA"] 

预期结果:

D <- data.table(
    cum_value = c(1.677,8.337,13.5,18.004,49.2165,115.947,130.4665,151.822,268.222,346.3065), 
    ask_price = c(NA,NA,11.25,11.26,11.35,NA,12.5,NA,NA,14.2), 
    ask_amount = c(NA,NA,1.2,0.4,2.75,NA,6.5,NA,NA,15.2), 
    ask_cum_amount = c(0.149066666666667,0.741066666666667,1.2,1.6,4.35,9.66496172396059,10.85,12.3126600707381,20.4097766460076,26.05), 
    ask_avg_price = c(11.25,11.25,11.25,11.2525,11.31414,11.9966331281534,12.02456,12.3305605066459,13.1418390633132,13.29392), 
    bid_price = c(11.18,11.1,NA,NA,NA,10.55,NA,10.25,9.7,NA), 
    bid_amount = c(0.15,0.6,NA,NA,NA,10.2,NA,3.5,12,NA), 
    bid_cum_amount = c(0.15,0.75,1.23858478466587,1.66517233847558,4.6230572556498,10.95,12.3652404387114,14.45,26.45,NA), 
    bid_avg_price = c(11.18,11.116,10.8995364444444,10.8120940902022,10.6458772362927,10.58877,10.5510685899445,10.50671,10.14072,NA) 
) 
print(D) 

注意的是,在预期结果最后NA仍然为NA,这是因为相反的顺序无法匹配,因为市场深度不够满足不惜任何代价的顺序。

是否有可能使用矩阵代数或data.table操作或任何其他有效的方法来避免在整个数据集上循环来获得预期结果?

在此先感谢

+0

你的公式使用'avg_price'和'price'这两者都不存在于你的'data.table'中。你能澄清吗? – Arun

+0

@Arun,计算公式ask_avg_price使用ask_ *,公式计算bid_avg_price使用bid_ *,只有cum_value字段对于两个集合都是通用的,不应以公式中的询问/出价为前缀。 – jangorecki

回答

1

AB再次合并其与roll找到最后一个/下非NA价格。

E.g.看到bid_avg_price输出值这两个合并:

B[merge(A, B, all = T), roll = Inf] 
B[merge(A, B, all = T), roll = -Inf] 

这应该给你你需要计算这些数量中的所有信息。

+0

谢谢,使用你的建议,我能够:1.以独特的方式加入A和B(c(A_key,B_key)),2.对A和B执行自连接以获得prev非NA和下一个非NA ,3.合并已填充NA的A和B并获得预期结果。 CPU时间非常出色。代码长15行,看起来不够可读。我认为它还是可以改进的。休息几周后,阅读起来很难。无论如何,感谢一些新技能! – jangorecki

+0

@MusX例如,如果交易订单已被越过(例如在拍卖中),并且您发现最大化填充量(不交叉价格)的价格,那么我会理解此操作。但是在这个例子中,这本书并没有跨越:最佳出价<最佳问题,正如连续会议一样。我错过了什么吗? –

+0

@MatthewDowle,就像在这个例子中,订单簿中的询问/出价没有交叉,如果交叉,他们将不会在订单簿中列出,而是在过去的交易(填充订单)中列出。操作要点是要求出价和出价要求出价和出价。此操作产生的结果是avg_price(cum_value),如公式(ask_avg_price(cum_value)+ bid_avg_price(cum_value))/ 2,此avg_price显示未结订单在其累计值中的分配。我很乐意听到关于我的逻辑的评论,这是一种没有金融知识背景的DIY。 – jangorecki