pbee
pbee

Reputation: 183

Summation of matrices in separate tibble list columns

I have a tibble data frame with two list columns. Within the list column mat_base, each row contains a 2x2 matrix. In the list column mat_sim, each row contains a list of 10 2x2 matrices. I would like to create a new list column mat_out, which is the sum of the mat_base matrix and each of the mat_sim matrices (within a given row). I.e. Each row of mat_out should contain a list of 10 matrices.

I assume there is a way to do this using lapply or the purrr library, but I haven't been able to figure it out. Any help appreciated.

library(tibble)    
library(dplyr)
library(purrr)

mat_base <- list(diag(2) * 1, diag(2) * 2, diag(2) * 3)

mat_sim_a <- replicate(10, matrix(rnorm(4), nrow = 2), simplify = F)
mat_sim_b <- replicate(10, matrix(rnorm(4), nrow = 2), simplify = F)
mat_sim_c <- replicate(10, matrix(rnorm(4), nrow = 2), simplify = F)

dat <- tibble(group = c('a', 'b', 'c')) %>% 
  mutate(mat_base = mat_base,
         mat_sim = list(mat_sim_a, mat_sim_b, mat_sim_c))

# doesn't work
dat %>% 
  mutate(mat_out = lapply(.$mat_sim, function(x, y) x + y, y = .$mat_base))

# doesn't work
dat %>% 
  mutate(mat_out = purrr::map(.$mat_sim, function(x, y) x + y, y = .$mat_base))

Upvotes: 2

Views: 303

Answers (2)

akrun
akrun

Reputation: 887213

We could use a nested map2 to get the + of 'mat_base' and 'mat_sim' to create the 'mat_out' as a column

dat %>% 
    mutate(mat_out = map2(mat_base, mat_sim, ~ 
                                    map2(list(.), .y, `+`)))
# A tibble: 3 x 4
#   group mat_base      mat_sim     mat_out    
#  <chr> <list>        <list>      <list>     
#1 a     <dbl [2 x 2]> <list [10]> <list [10]>
#2 b     <dbl [2 x 2]> <list [10]> <list [10]>
#3 c     <dbl [2 x 2]> <list [10]> <list [10]>

Upvotes: 2

Pdubbs
Pdubbs

Reputation: 1987

You can solve the issue by using lapply on position rather than the actual list, which lets you access nested levels:

dat %>% 
  mutate(mat_out = lapply(1:3, function(x) 
    lapply(dat$mat_sim[[x]],function(y) y+dat$mat_base[[x]])))

Upvotes: 1

Related Questions