Even messier than @Pgibas solution:
dt[, list(c(sales_ccy, cost_ccy),c(sum(sales_amt), sum(cost_amt))), # this will create two new columns with ccy and amt by=list(sales_ccy, cost_ccy) # nro of rows reduced to only unique combination ales_ccy, cost_ccy ][, sum(V2), # this will aggregate the new columns by=V1 ]
Benchmark
I did a couple of tests to check my code for a solution with data table 1.9.5 proposed by Arun.
Just an observation, I just generated 500K + rows duplicating the original data table. This reduced the number of sales_ccy / cost_ccy pairs, which also reduced the number of rows dropped by the second data.table [] (only 8 rows were created in this case).
I donβt think that in the real world scenario the number of rows returned will be about 500K + (maybe, but I studied this thing a while ago, N ^ 2, where N is the amount of currency used), but this is something else to have in mind by looking at these results.
library(data.table) library(microbenchmark) rm(dt) dt <- data.table(sales_ccy = c("USD", "EUR", "GBP", "USD"), sales_amt = c(500,600,700,800), cost_ccy = c("GBP","USD","GBP","USD"), cost_amt = c(-100,-200,-300,-400)) dt for (i in 1:17) dt <- rbind(dt,dt) mycode <-function() { test1 <- dt[, list(c(sales_ccy, cost_ccy),c(sum(sales_amt), sum(cost_amt))),
Result
Unit: milliseconds expr min lq mean median uq max neval mycode() 12.27895 12.47456 15.04098 12.80956 14.73432 45.26173 100 suggesteEdit() 25.36581 29.56553 42.52952 33.39229 59.72346 69.74819 100 meltWithDataTable195() 25.71558 30.97693 47.77700 58.68051 61.23996 66.49597 100