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
CodePudding user response:
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
CodePudding user response:
We could use 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