r - matrix operations and component-wise addition using data.table -
r - matrix operations and component-wise addition using data.table -
what best way component-wise matrix add-on if number of matrices summed not known in advance? more generally, there way perform matrix (or multi-dimensional array) operations in context of data.table? utilize data.table
efficiency @ sorting , grouping info several fixed variables, or categories, each comprising different number of observations.
for example:
find outer product of vector components given in each observation (row) of data, returning matrix each row. sum resulting matrices component-wise on rows of each grouping of info categories.here illustrated 2x2 matrices , 1 category:
library(data.table) # illustration data, number of rows differs category t n <- 5 dt <- data.table(t = rep(c("a", "b"), each = 3, len = n), x1 = rep(1:2, len = n), x2 = rep(3:5, len = n), y1 = rep(1:3, len = n), y2 = rep(2:5, len = n)) setkey(dt, t) > dt t x1 x2 y1 y2 1: 1 3 1 2 2: 2 4 2 3 3: 1 5 3 4 4: b 2 3 1 5 5: b 1 4 2 2
i attempted function compute matrix sum on outer product, %o%
mat_sum <- function(x1, x2, y1, y2){ x <- c(x1, x2) # x vector y <- c(y1, y2) # y vector xy <- x %o% y # outer product (i.e. 2x2 matrix) sum(xy) # <<< returns single value, not want. }
which, of course, not work because sum
adds elements across arrays.
i saw this answer using reduce('+', .list)
seems require having list
of matrices added. haven't figured out how within data.table
, instead i've got cumbersome work-around:
# extract each outer product component first... mat_comps <- function(x1, x2, y1, y2){ x <- c(x1, x2) # x vector y <- c(y1, y2) # y vector xy <- x %o% y # outer product (i.e. 2x2 matrix) xy11 <- xy[1,1] xy21 <- xy[2,1] xy12 <- xy[1,2] xy22 <- xy[2,2] return(c(xy11, xy21, xy12, xy22)) } # ...then running function on dt, # taking step (making column 'n') apply row-by-row... dt[, n := 1:nrow(dt)] dt[, c("xy11", "xy21", "xy12", "xy22") := as.list(mat_comps(x1, x2, y1, y2)), = n] # ...then sum them individually, grouping t s <- dt[, list(s11 = sum(xy11), s21 = sum(xy21), s12 = sum(xy12), s22 = sum(xy22)), = key(dt)] > s t s11 s21 s12 s22 1: 8 26 12 38 2: b 4 11 12 23
and gives summed components, can converted matrices.
in general, data.table
designed work columns. more transform problem col-wise operations, more can out of data.table
.
here's effort @ accomplishing operation col-wise. there improve ways. intended more template, provide thought on approaching problem (even though understand may not possible in cases).
xcols <- grep("^x", names(dt)) ycols <- grep("^y", names(dt)) combs <- cj(ycols, xcols) len <- seq_len(nrow(combs)) cols = paste("v", len, sep="") (i in len) { c1 = combs$v2[i] c2 = combs$v1[i] set(dt, i=null, j=cols[i], value = dt[[c1]] * dt[[c2]]) } # t x1 x2 y1 y2 v1 v2 v3 v4 # 1: 1 3 1 2 1 3 2 6 # 2: 2 4 2 3 4 8 6 12 # 3: 1 5 3 4 3 15 4 20 # 4: b 2 3 1 5 2 3 10 15 # 5: b 1 4 2 2 2 8 2 8
this applies outer product col-wise. it's matter of aggregating it.
dt[, lapply(.sd, sum), by=t, .sdcols=cols] # t v1 v2 v3 v4 # 1: 8 26 12 38 # 2: b 4 11 12 23
hth
edit: modified cols, c1, c2
bit output right order v2
, v3
.
r matrix data.table outer-join
Comments
Post a Comment