这是我的数据的最小工作示例:
library(data.table)
df <- data.table(date=as.Date(c("1999-01-04","1999-01-04","1999-01-04","1999-01-04","1999-01-04","1999-01-04","1999-01-04","1999-01-04")),volume=c(1000,1000,1200,1250,1200,1300,1250,1200),cp_flag=c("P","C","C","P","C","C","P","P"),price_in=c(10.1,120.4,100.3,0.1,90.2,45.7,99.1,7.4), price_out=c(12.4,122.1,102.0,0.6,99.1,48.1,100.0,8.1), dtm=c(10,10,12,12,12,15,15,12))
setorder(df,date,dtm,volume)
df
date volume cp_flag price_in price_out dtm
1: 1999-01-04 1000 P 10.1 12.4 10
2: 1999-01-04 1000 C 120.4 122.1 10
3: 1999-01-04 1200 C 100.3 102.0 12
4: 1999-01-04 1200 P 7.4 8.1 12
5: 1999-01-04 1200 C 90.2 99.1 13
6: 1999-01-04 1250 P 0.1 0.6 12
7: 1999-01-04 1250 P 99.1 100.0 15
8: 1999-01-04 1300 C 45.7 48.1 15
我的目标是:每个日期我想计算具有相同1)音量和2)dtm(又名持续时间)的所有项目的惯用功能,具体取决于它是否为“ C“或”P“产品,例如:volume/10+price_in[cp_flag=="C"]-price_out[cp_flag=="P"]
。
这里的另一个难点是每个日期/体积/ dtm组合可能有不同数量的“P”和“C”(例如参见体积= 1200),我想将其视为如下所述。
作为输出我寻找
date volume dtm
1: 1999-01-04 1000 10
2: 1999-01-04 1200 12
3: 1999-01-04 1200 13
4: 1999-01-04 1250 12
5: 1999-01-04 1250 15
6: 1999-01-04 1300 15
附加列表示上述函数的结果,表的长度由所有日期/体积/ dtm以下列方式确定:
price_in[cp_flag="C"]
和price_out[cp_flag="C"]
值执行该功能,并且结果的长度与原始表我相信这可以通过data.table方法有效地完成,但我还是不能让它工作。
在.SD
s上操作似乎很自然。所以我首先尝试通过
df[,print(.SD),by=.(date,volume,dtm),.SDcols=c("price_in","price_out","volume","cp_flag")]
这给了我所有想要的组合:
price_in price_out cp_flag
1: 10.1 12.4 P
2: 120.4 122.1 C
price_in price_out cp_flag
1: 100.3 102.0 C
2: 7.4 8.1 P
price_in price_out cp_flag
1: 90.2 99.1 C
price_in price_out cp_flag
1: 0.1 0.6 P
price_in price_out cp_flag
1: 99.1 100 P
price_in price_out cp_flag
1: 45.7 48.1 C
但现在我不确定如何计算惯用函数,即检查每组中有多少“C”和“P”,然后计算上面的公式,即volume/10+price_in[cp_flag=="C"]-price_out[cp_flag=="P"]
表示所有C和普的。但是,如果只有C或P只使用他们的信息,即price_in和price_out的相同产品。
对于第一部分,我尝试过像
df[,lapply(.SD,function(x) x[cp_flag=="C",volume/10]+x[cp_flag=="C",price_in]-x[cp_flag=="P",price_out]),by=.(date,volume,dtm),.SDcols=c("price_in","price_out","volume","cp_flag")]
但这失败了,因为在这种情况下我似乎误解了如何使用自定义函数。
问题:如何在具有此类附加案例结构的数据表的子集上正确使用此类自定义函数?
注意:我知道这个例子看起来很复杂,也许我已经太深了,可能花了太多时间来破解它,但我看不出更简单的方式来呈现我的问题。如果我有任何进一步的许可,请告诉我。任何帮助都非常感谢!
答案 0 :(得分:2)
我猜是这样的:
res = df[, {
flags = sort(unique(cp_flag))
n_flags = length(flags)
if (n_flags == 1L)
.(g = .GRP, price_in, price_out, flags = flags)
else CJ(
g = .GRP,
price_in = price_in[cp_flag == "C"],
price_out = price_out[cp_flag == "P"],
flags = toString(flags)
)
}, by=.(date, volume, dtm)][, v := volume/10 + price_in - price_out][]
date volume dtm g price_in price_out flags v
1: 1999-01-04 1000 10 1 120.4 12.4 C, P 208.0
2: 1999-01-04 1200 12 2 90.2 8.1 C, P 202.1
3: 1999-01-04 1200 12 2 100.3 8.1 C, P 212.2
4: 1999-01-04 1250 12 3 0.1 0.6 P 124.5
5: 1999-01-04 1250 15 4 99.1 100.0 P 124.1
6: 1999-01-04 1300 15 5 45.7 48.1 C 127.6
我不会说这是有效的,但至少计算是以矢量化方式完成的。