矩阵和数据框之间的逐行差异
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
我有 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