矩阵和数据框之间的逐行差异

Row-wise difference between matrix and data frame

我有 2 个对象:m1 是行数随时间增加的矩阵,m2 是行数随时间减少的数据框。两者共享共同的列名(即行、列)。我想要的是找到 m1 的第一行和 m2 的每一行之间的区别,并将输出作为对象存储在列表中。对于 m1.

的后续行,这应该继续

我试过 apply(m1, 1, function(x){x - m2}),但这给了我一个我无法解释的结果(即,从第二次观察开始,差异就没有意义了)。为什么会发生这种情况,可以采取哪些措施来确保按要求返回差异?

数据、代码及当前输出:

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

期望输出:

[[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

我们可以试试下面的代码

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

这给出了

[[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

或者,另一个选项使用 Map + split + rep

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

这给出了

$`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

我们可以使用 sweep

my_function <- function(m1, m2){
  x <- as.vector(m1[1,])
  y <- as.vector(m1[2,])
  m2_1 <- sweep(m2, 2, x, `-`)*-1
  m2_2 <- sweep(m2, 2, y, `-`)*-1
  list(m2_1,m2_2)
}

my_function(m1, m2)

my_function(m1, m2)
[[1]]
  X1 X2
1  0  0
2 -2 -2
3 -4 -4
4 -6 -6
5 -8 -8

[[2]]
  X1 X2
1  2  2
2  0  0
3 -2 -2
4 -4 -4
5 -6 -6