Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Row-wise difference between matrix and data frame

I have 2 objects: m1 is a matrix that increases in rows over time, and m2 is a data frame that decreases in rows over time. Both share common column names (i.e., row, col). What I want is to find the difference between the first row of m1 and each row of m2 and have the output stored as an object in a list. This should continue for the subsequent rows of m1.

I have tried with apply(m1, 1, function(x){x - m2}), but this gives me a result I cannot explain (i.e., the difference doesn't make sense from the second observations onwards). Why is this happenning and what can be done to ensure the difference is returned as desired?

Data, code and current output:

m1 <- matrix(1:4, ncol = 2, byrow = T) 
m2 <- data.frame(matrix(1:10, ncol = 2, byrow = T))
colnames(m1) <- colnames(m2) <- c("row", "col")

> m1
     row col
[1,]   1   2
[2,]   3   4
> m2
  row col
1   1   2
2   3   4
3   5   6
4   7   8
5   9  10
> apply(m1, 1, function(x){x - m2})
[[1]]
  row col
1   0   0
2  -1  -3
3  -4  -4
4  -5  -7
5  -8  -8

[[2]]
  row col
1   2   2
2   1  -1
3  -2  -2
4  -3  -5
5  -6  -6

Desired output:

[[1]]
  row col
1   0   0
2  -2  -2
3  -4  -4
4  -6  -6
5  -8  -8

[[2]]
  row col
1   2   2
2   0   0
3  -2  -2
4  -4  -4
5  -6  -6
like image 737
altfi_SU Avatar asked Aug 08 '26 15:08

altfi_SU


1 Answers

We can try the code below

apply(
  m1,
  1,
  function(x) {
    t(x - t(m2))
  },
  simplify = FALSE
)

which gives

[[1]]
     row col
[1,]   0   0
[2,]  -2  -2
[3,]  -4  -4
[4,]  -6  -6
[5,]  -8  -8

[[2]]
     row col
[1,]   2   2
[2,]   0   0
[3,]  -2  -2
[4,]  -4  -4
[5,]  -6  -6

Or, another option using Map + split + rep

Map(
  `-`,
  split(m1[rep(1:nrow(m1), each = nrow(m2)), ], gl(nrow(m1), nrow(m2))),
  list(m2)
)

which gives

$`1`
  row col
1   0   0
2  -2  -2
3  -4  -4
4  -6  -6
5  -8  -8

$`2`
  row col
1   2   2
2   0   0
3  -2  -2
4  -4  -4
5  -6  -6
like image 69
ThomasIsCoding Avatar answered Aug 11 '26 07:08

ThomasIsCoding



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!