Dividing matrices with unequal dimensions in r

I have a data set that I had filtered into a single month. I also have a list of matrices (l1) that is the same length as the list of data frames (int1). The matrices in the list have different dimensions (e.g.,3x3, 2x2).

Setting the data and list:

library(lubridate)
library(tidyverse)
library(purrr)

date <- rep_len(seq(dmy("26-12-2010"), dmy("13-07-2011"), by = "days"), 200)
ID <- rep(c("A","B"), 100)
df <- data.frame(date = date,
                 x = runif(length(date), min = 60000, max = 80000),
                 y = runif(length(date), min = 800000, max = 900000),
                 ID)

df$jDate <- julian(as.Date(df$date), origin = as.Date('1970-01-01'))
df$Month <- month(df$date)

# First 10-day interval for `A`
t1 <- c(100,150,200)
# Second 10-day interval for `A`
t2 <- c(200,250,350)
# Third 10-day interval for `A`
t3 <- c(300,350, 400)
mat <- cbind(t1,t2, t3)

# First 10-day interval for `B`
t1 <- c(150,150)
# Second 10-day interval for `B`
t2 <- c(250,250)
mat2 <- cbind(t1,t2)

l1 <- list(mat, mat2)

int1 <- df %>%
  # arrange(ID) %>%   # skipped for readability of result
  mutate(new = floor_date(date, '10 day')) %>%
  mutate(new = if_else(day(new) == 31, new - days(10), new)) %>% 
  group_by(ID, new) %>%
  filter(Month == "3") %>% 
  group_split()

The code below attempts to divide lstMat from l1. The problem that I am running into is that matrices in lstMat do not have the same dimensions as the matrices in l1. Due this discrepency, when I try and divide one from the other I receive the error message: Error in .x/.y : non-conformable arrays

g1 <- as.integer(gl(length(int1), 3, length(int1)))

f2 <- function(.int1, .int2) {
  t(outer(seq_along(.int1), seq_along(.int2), 
          FUN = Vectorize(function(i, j)  min(.int1[[i]]$jDate) - 
                            min(.int2[[j]]$jDate))))
}
lstMat <- map2(split(int1, g1), split(int1, g1), f2)
map2(l1, lstMat[1:2], `/`)

Any thoughts on how I can modify this code to allow for differences in matrices with the list?

Problem: I have matrices with different dimensions that I have been trying to divide. Let say I run a custom function and end with l1. The matrices in l1 correspond to the 10-day intervals in int1, but we didn't get an output for the third 10-day interval for ID B hence a 2x2 matrix.

Rules: In this case, I would like to remove the third column from lstMat[[2]] because that is the one missing from l1[[2]]. This wouldn't always be the case, for example if the second 10-day interval was missing from l1[[2]], then I would want to remove the second column in lsMat[[2]].

I would like to link lstMat and l1 through the use of int1 based on the specific intervals that end up getting removed from lstMat.

I hope I didn't make this more confusing. I apologize if I did.

Thank you for your time.


Solution 1:

Here the 'g1' needs to be dynamic based on the number of rows/dimensions of each of the elements in 'lstMat'. This can be done with rep

library(purrr)
g1 <- rep(seq_along(lstMat), sapply(lstMat, nrow))
lstMat <- map2(split(int1, g1), split(int1, g1), f2)
map2(l1, lstMat[1:2], `/`)
[[1]]
      t1  t2  t3
[1,] Inf  20  15
[2,] -15 Inf  35
[3,] -10 -35 Inf

[[2]]
      t1  t2
[1,] Inf  25
[2,] -15 Inf

Some values are Inf only because we have some values in the 'lstMat' as '0'

lstMat[1:2]
$`1`
     [,1] [,2] [,3]
[1,]    0   10   20
[2,]  -10    0   10
[3,]  -20  -10    0

$`2`
     [,1] [,2]
[1,]    0   10
[2,]  -10    0

Thus any value divided by 0 returns Inf