2017-01-16 48 views
13

Karşılaştığım iki tablo var. Tablo 1, zaman periyotlarını, yani yıl sonunda yılın ve çeyreğin (yani, 4, 8, 12 vb.) Içerir. Tablo 2 çeyrek 3, 6 en Yıl içinde işlemlerini içeren 7 vbİki tabloda nasıl özetlenir?

Ben yıl sonunda kümülatif pozisyon almak, böylece yıl boyunca tüm işlemleri toplamak Tablo 3 gerekir.

Burada veri benziyor ve açıklamak için bazı örnek kod ne çıktı gibi görünmelidir: Ben merge, summarise, foverlaps denedim ama oldukça onu anlamaya olamaz

library(data.table) 

x1 <- data.table("Name" = "LOB1", "Year" = 2000, 
       "Quarter" = c(4, 8, 12, 16, 20, 24, 28, 32, 36)) 
x2 <- data.table("Name" = "LOB1", "Year" = 2000, 
       "Quarter" = c(3, 6, 7, 9, 11, 14, 16, 20, 24), 
       "Amount" = c(10000, 15000, -2500, 3500, -6500, 25000, 
           11000, 9000, 7500)) 
x3 <- data.table("Name" = "LOB1", "Year" = 2000, 
       "Quarter" = c(4, 8, 12, 16, 20, 24, 28, 32, 36), 
       "Amount" = c(10000, 22500, 19500, 55500, 64500, 72000, 
           72000, 72000, 72000)) 

.

cevap

11

Güzel soru. Temelde yapmaya çalıştığınız, eşleşen tüm Amount değerlerini toplarken Name, Year ve Quarter <= Quarter'a katılmaktır. Bu yeni olmayan equi kullanarak hem mümkündür (ikincisi muhtemelen optimumun olacak ise) ve foverlaps (son kararlı data.table v 1.10.0 sürümünde tanıtıldı olan) katılır

Olmayan equi katılır:

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 
bir yan not olarak

, kolayca (@Frank önerdiği) x1 yerinde Amount ekleyebilirsiniz:

x1[, Amount := 
    x2[x1, sum(x.Amount), on = .(Name, Year, Quarter <= Quarter), by = .EACHI]$V1 
] 

Bu tablodaki üç birleştirme sütunundan fazlasına sahipseniz, bu kullanışlı olabilir.


foverlaps: Teoride siz de bu işlevi kullanarak aynı elde edebiliriz böylece

Sen foverlaps bahsettiniz. Korkarım ki kolayca hafızanızdan kurtulacaksınız. foverlaps kullanarak, çok

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 
+0

Teşekkür x2 her değer x1 her değere defalarca katılmış büyük bir tablo oluşturmak ve hafızadaki her şeyi saklamak gerekir - Sadece bu çalışma var. Çok müteşekkirim! Her iki tablonun da içinde aynı sütunlara sahip olması gerekiyor. X2 sonuçta elde edemediğim ek bir sütuna sahip olsaydı, x3 sonuçta, kod aynı olurdu? – kodfather

+0

Her iki tablonun istediğiniz sütun adlarının ne olduğunu 'on' argümanında belirtebilirsiniz. Örneğin .on (column1 = column2, column3 = column4), vb. Suasionun LHS'si, x1'in sütunlarıdır, denklemin RHS'si ise x2'den sütunlardır. –