Ответ 1
Хороший вопрос. В основном вы пытаетесь присоединиться к Name
, Year
и Quarter <= Quarter
, суммируя все сопоставленные значения Amount
. Это возможно и с использованием новых неравновесных объединений (которые были введены в последней стабильной версии data.table v-1.10.0) и foverlaps
(в то время как последняя будет, вероятно, субоптимальной)
Non-Equi объединяет:
x2[x1, # for each value in `x1` find all the matching values in `x2`
.(Amount = sum(Amount)), # Sum all the matching values in `Amount`
on = .(Name, Year, Quarter <= Quarter), # join conditions
by = .EACHI] # Do the summing per each match in `i`
# Name Year Quarter Amount
# 1: LOB1 2000 4 10000
# 2: LOB1 2000 8 22500
# 3: LOB1 2000 12 19500
# 4: LOB1 2000 16 55500
# 5: LOB1 2000 20 64500
# 6: LOB1 2000 24 72000
# 7: LOB1 2000 28 72000
# 8: LOB1 2000 32 72000
# 9: LOB1 2000 36 72000
В качестве дополнительной заметки вы можете легко добавить Amount
в место в x1
(предложенном @Frank):
x1[, Amount :=
x2[x1, sum(x.Amount), on = .(Name, Year, Quarter <= Quarter), by = .EACHI]$V1
]
Это может быть удобно, если в этой таблице имеется не только три столбца соединения.
foverlaps:
Вы упомянули foverlaps
, поэтому теоретически вы можете добиться того же, используя эту функцию. Хотя я боюсь, вы легко избавитесь от памяти. Используя foverlaps
, вам нужно создать огромную таблицу, в которой каждое значение в x2
соединяется несколько раз с каждым значением в x1
и сохраняет все в памяти
x1[, Start := 0] # Make sure that we always join starting from Q0
x2[, Start := Quarter] # In x2 we want to join all possible rows each time
setkey(x2, Name, Year, Start, Quarter) # set keys
## Make a huge cartesian join by overlaps and then aggregate
foverlaps(x1, x2)[, .(Amount = sum(Amount)), by = .(Name, Year, Quarter = i.Quarter)]
# Name Year Quarter Amount
# 1: LOB1 2000 4 10000
# 2: LOB1 2000 8 22500
# 3: LOB1 2000 12 19500
# 4: LOB1 2000 16 55500
# 5: LOB1 2000 20 64500
# 6: LOB1 2000 24 72000
# 7: LOB1 2000 28 72000
# 8: LOB1 2000 32 72000
# 9: LOB1 2000 36 72000