Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R:子集上的data.table自定义函数_R_Data.table - Fatal编程技术网

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按以下方式确定:

  • 如果正好有1个“P”乘积和1个“C”乘积(如第一个组合),则公式的计算很简单,得到1个结果
  • 如果存在多个“P”产品和1个“C”产品,或者相反,则结果列中有一个条目,用于“P”和“C”产品之间的所有交叉组合
  • 如果存在多个“P”产品和多个“C”产品,则相同,即“C”和“P”之间的所有可能交叉组合都被采用
  • 如果只有一种产品/类别(例如C),则使用相同产品的
    price\u in[cp\u flag=“C”]
    price\u out[cp\u 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”,然后计算上面的公式,即所有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