R data.table - 通过聚合满足条件的其他行来更新每一行

问题描述 投票:0回答:1

我有下表。

dt = data.table(id = 1:5, intMask = c(11,14,8,1,13), imprint = c("1011", "1110", "1000", "0001", "1101"), N = c(3,3,1,1,3), mass = c(.05,.1,.15,.3,.4))

   id intMask imprint N mass
1:  1      11    1011 3 0.05
2:  2      14    1110 3 0.10
3:  3       8    1000 1 0.15
4:  4       1    0001 1 0.30
5:  5      13    1101 3 0.40

假设

imprint
列表示一个集合的二进制表示(即这里我们有基数为 5 的集合的子集)。
intMask
表示对应于二进制表示的各个整数。
N
各自的基数 - 即表示中 1 的数量。 我想通过对对应于各个超集的所有行求和来更新
sum
。我建议使用
bitwAnd()
函数和
intMask
列来有效地找到相应的超集。

for(i in 1:nrow(dt)) {
  i.intMask <- dt[i,intMask]
  i.N <- dt[i,N]
  dt[i, newMass := sum(dt[N >= i.N,][bitwAnd(intMask, i.intMask) == i.intMask, mass])]
}

即得到

dt[]
   id intMask imprint N mass newMass
1:  1      11    1011 3 0.05    0.05
2:  2      14    1110 3 0.10    0.10
3:  3       8    1000 1 0.15    0.70
4:  4       1    0001 1 0.30    0.75
5:  5      13    1101 3 0.40    0.04

假设有数千行。您知道如何有效地做到这一点吗?最好使用

data.table
更新?

r data.table
1个回答
0
投票

这可能是一种选择

dt[
    dt[dt,
        c(
            id = .(i.id),
            newMass = .(mass * (bitwAnd(intMask, i.intMask) == i.intMask))
        ),
        on = .(N >= N)
    ][, .(newMass = sum(newMass)), id],
    on = "id"
]

这给出了

      id intMask imprint     N  mass newMass
   <int>   <num>  <char> <num> <num>   <num>
1:     1      11    1011     3  0.05    0.05
2:     2      14    1110     3  0.10    0.10
3:     3       8    1000     1  0.15    0.70
4:     4       1    0001     1  0.30    0.75
5:     5      13    1101     3  0.40    0.40
© www.soinside.com 2019 - 2024. All rights reserved.