R:子集上的data.table自定义函数
下面是我的数据的一个最简单的工作示例:R:子集上的data.table自定义函数,r,data.table,R,Data.table,下面是我的数据的一个最简单的工作示例: 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","
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
另一列表示上述函数的结果,其中表格的长度由所有日期/体积/dtm按以下方式确定:
price\u in[cp\u flag=“C”]
和price\u out[cp\u flag=“C”]
值执行该功能,结果的长度与原始表中的长度相同.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”,然后计算上面的公式,即所有C和p的volume/10+price\u in[cp\u flag==“C”]-price\u out[cp\u flag==“p”]
。但如果只有Cs或Ps,则仅使用其信息,即相同产品的价格输入和价格输出。
在第一部分中,我尝试了以下方法
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")]
但这失败了,因为我显然误解了在这种情况下如何使用自定义函数
问题:如何在具有此类附加大小写结构的数据表子集上正确使用此类自定义函数
注意:我知道这个例子看起来很复杂,可能我已经太深了,可能花了太多时间来破解它,但我看不到一个更简单的方法来表达我的问题。如果有任何进一步的许可我可以给,请让我知道。非常感谢您的帮助 我想就是这样:
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
我不认为这是有效的,但至少计算是以矢量化的方式完成的。我认为这是本机日期格式?例如%YYYY-%MM-%DD,假设它是as.Date()的默认格式?啊,现在我明白你的意思了。添加了“as.Date”谢谢。我在文中提到过(‘P’和‘C’的向量),但现在也将其编辑到枚举中,以便更好地参考Hanks Frank!很有魅力
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