简体   繁体   中英

How to store results in a matrix with a loop function in R

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!

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

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

data

x <- matrix(1:20, nrow = 10)
y <- matrix(1:6, nrow = 3)

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?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM