Reputation: 31
I have been trying to create a vector or a matrix with a loop, but instead, it just creates a variable with the value of the last loop.
I have a 100x2 tableX and a 10x2 tableY. I need to multiply each row from table1 by rows in table2 and store the results in a matrix. (X[1,1]*Y[1,1]+X[1,2]*Y[1,2] and so on)
So in the end I need a 100x10 matrix that would contain the multiplications.
I manage to create the following loop just for the first row from tableY, so it prints the first vector of the resulting table that I need.
for (i in seq(1,100))) {
results <- ((tableX[i,1]* tableY[1,1])+(tableX[i,2]* tableY[1,2]))
print(results)
}
My question is, how do I store this printout as a vector, and then do the same of other rows of tableY?
Thank you in advance!
Upvotes: 3
Views: 2462
Reputation: 12703
Here is one way to do it:
Data:
x <- matrix(1:20, nrow = 10)
y <- matrix(1:6, nrow = 3)
Code:
method-1: (RECOMMENDED)
dimensions:
x = 10 by 2
t(y) = 2 by 3
x*t(y) = 10 by 3
# dot product of x and transpose of y
x %*% t(y)
# [,1] [,2] [,3]
# [1,] 45 57 69
# [2,] 50 64 78
# [3,] 55 71 87
# [4,] 60 78 96
# [5,] 65 85 105
# [6,] 70 92 114
# [7,] 75 99 123
# [8,] 80 106 132
# [9,] 85 113 141
# [10,] 90 120 150
method-2
y <- t(y)
apply(x, 1, function(m) colSums(m*y))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 45 50 55 60 65 70 75 80 85 90
# [2,] 57 64 71 78 85 92 99 106 113 120
# [3,] 69 78 87 96 105 114 123 132 141 150
to convert to vector:
c(apply(x, 1, function(m) colSums(m*t(y))))
method:3
rowSums(matrix( c(apply(expand.grid(x[,1],y[,1]), 1, prod),
apply(expand.grid(x[,2],y[,2]), 1, prod)),
ncol = 2))
# [1] 45 50 55 60 65 70 75 80 85 90 57 64 71 78 85 92
# [17] 99 106 113 120 69 78 87 96 105 114 123 132 141 150
Upvotes: 3
Reputation: 886998
Here is another option with outer
in base R
c(Reduce(`+`, Map(function(u, v) outer(u, v), asplit(x, 2), asplit(y, 2))))
#[1] 45 50 55 60 65 70 75 80 85 90
#[11] 57 64 71 78 85 92 99 106 113 120
#[21] 69 78 87 96 105 114 123 132 141 150
x <- matrix(1:20, nrow = 10)
y <- matrix(1:6, nrow = 3)
Upvotes: 2
Reputation: 6073
You need something with a [i] index on the left-hand side of your assignment. The general structure is something like this, assuming 100 iterations through the loop:
# initialize an empty object (here a vector) to store results
results <- rep(NA, 100)
# loop and store results
for (i in seq(100)) {
<do some calcs>
results[i] <- <value to save>
}
Then the object results
will have the saved values from each iteration of the loop.
If you are storing more than 1 value each time through the loop, you could save your results in a matrix or list. For a list, the loop is basically the same, and you could initialize the empty list object as:
results <- vector(mode="list", length=100)
Upvotes: 1
Reputation: 321
Try setting up your result matrix with empty values before hand, to initialize it then use the indexing of the loop to fill it.
If your vector will always be the same length then you can change your results line to this: The length(vector) is obviously replaced with the number of columns you expect.
results[i,1:length(vector)] <- ((tableX[i,1]* tableY[1,1])+(tableX[i,2]* tableY[1,2]))
I'm not sure this answers your full questions, it sounds like you want to loop over two values. Do you have example tables to simplify the question?
Upvotes: 1