【问题标题】:Weighted row average in time series join时间序列连接中的加权行平均值
【发布时间】:2014-05-20 15:39:17
【问题描述】:

您好,我正在寻找解决以下问题的最干净/最快的方法:

我的设置是这样的

library(data.table)
set.seed(1234)
DT1 <- data.table(replicate(12,runif(5)))
setnames(DT1,LETTERS[1:12])
DT1[,time:=100]
DT2 <- data.table(time=rep(100,12), grp=rep(c("X","Y","Z"),each=4),  
    sub=LETTERS[1:12], weight=sample(1:100,12))

options(digits=2)
DT1
     A      B    C    D    E     F    G    H    I    J     K    L time
1: 0.11 0.6403 0.69 0.84 0.32 0.811 0.46 0.76 0.55 0.50 0.074 0.50  100
2: 0.62 0.0095 0.54 0.29 0.30 0.526 0.27 0.20 0.65 0.68 0.310 0.49  100
3: 0.61 0.2326 0.28 0.27 0.16 0.915 0.30 0.26 0.31 0.48 0.717 0.75  100
4: 0.62 0.6661 0.92 0.19 0.04 0.831 0.51 0.99 0.62 0.24 0.505 0.17  100
5: 0.86 0.5143 0.29 0.23 0.22 0.046 0.18 0.81 0.33 0.77 0.153 0.85  100

> DT2
    time grp sub weight
 1:  100   X   A     87
 2:  100   X   B      5
 3:  100   X   C     32
 4:  100   X   D      2
 5:  100   Y   E     23
 6:  100   Y   F     68
 7:  100   Y   G     29
 8:  100   Y   H     48
 9:  100   Z   I     99
10:  100   Z   J     52
11:  100   Z   K     11
12:  100   Z   L     80

我想通过引用 DT2 中的组、子类和权重来计算 DT1 列的加权平均值(每行),同时加入每个时间点。

例如所以 DT1 然后将列 X、Y 和 Z 绑定到它,所以在这种情况下,第一行的 X 列是 87*0.11 + 5*0.64 + 32*0.69 + 2*0.84 / (87 + 5 + 32 + 2 )

DT1 中有数百万行具有不同的时间点,因此内存可能是一个限制因素

任何建议将不胜感激!

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    可能是这样的:

    library(reshape2)
    
    setkey(DT2, time, sub)
    
    DT2[melt(DT1, id.var = 'time')[, row := 1:.N, by = list(time, variable)]][,
        sum(weight * value) / sum(weight), by = list(time, grp, row)]
    #    time grp row   V1
    # 1:  100   X   1 0.29
    # 2:  100   X   2 0.57
    # 3:  100   X   3 0.51
    # 4:  100   X   4 0.69
    # 5:  100   X   5 0.69
    # 6:  100   Y   1 0.67
    # 7:  100   Y   2 0.36
    # 8:  100   Y   3 0.52
    # 9:  100   Y   4 0.71
    #10:  100   Y   5 0.31
    #11:  100   Z   1 0.50
    #12:  100   Z   2 0.59
    #13:  100   Z   3 0.51
    #14:  100   Z   4 0.39
    #15:  100   Z   5 0.59
    

    如果你喜欢,你也可以重新塑造上面的结果:

    # assuming you called the above table "res"
    dcast.data.table(res, row + time ~ grp)
    #Using 'V1' as value column. Use 'value.var' to override
    #   row time    X    Y    Z
    #1:   1  100 0.29 0.67 0.50
    #2:   2  100 0.57 0.36 0.59
    #3:   3  100 0.51 0.52 0.51
    #4:   4  100 0.69 0.71 0.39
    #5:   5  100 0.69 0.31 0.59
    

    【讨论】:

    • 完美,非常感谢!好奇这种用于分别处理每一行的 DT[,...][,...] 技术是否完全利用了 data.table 优化,还是使用 data.frame 一样快?
    • @user3657159 上面的表达式不适用于data.frames,base中的类似操作会慢很多
    猜你喜欢
    • 1970-01-01
    • 2019-06-02
    • 2012-06-06
    • 1970-01-01
    • 2019-07-24
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多