coding_heart
coding_heart

Reputation: 1295

How to store matrices inside a loop in R

I've got a simple question that I can't figure out: I would like to store matrices produced in a loop into one full storage matrix. For example, the following code generates a matrix 5x5 each iteration for three iterations but is unable to store them into one 5x15 matrix:

species_samp <- sample(unique(iris$Species))
store <- matrix(NA, ncol =5, nrow = 15)

for(i in 1:3){

    samp    <- iris[sample(nrow(iris[iris$Species==species_samp[i],]), 5),]
    store[i,] <- samp
}   

This fails, however I would like to ultimately have a store matrix with the the full matrix that gets sampled in each iteration of the loop. Any and all help appreciated. Thanks.

Upvotes: 1

Views: 3366

Answers (2)

Scott Ritchie
Scott Ritchie

Reputation: 10543

As ALiX has pointed out, you need to properly index your store matrix inside your for loop. At the moment you're attempting to assign each matrix to an individual row, so you'll get an error like this:

Error in store[i,] <- samp : 
  number of items to replace is not a multiple of replacement length

Instead you need to assign it to the correct number of rows. You'll also need to make store a data.frame instead of a matrix, and fix the column names and Species column afterwards:

species_samp <- sample(unique(iris$Species))
store <- as.data.frame(matrix(NA, ncol =5, nrow = 15))
for(i in 1:3){
    samp    <- iris[sample(nrow(iris[iris$Species==species_samp[i],]), 5),]
    store[(((i-1)*5)+1):(i*5),] <- samp
}
names(store) <- names(samp)
store$Species <- as.factor(store$Species)
levels(store$Species) <- levels(iris$Species)
samp

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.8         4.0          1.2         0.2  setosa
2           5.0         3.0          1.6         0.2  setosa
3           5.1         3.8          1.5         0.3  setosa
4           5.1         3.4          1.5         0.2  setosa
5           4.6         3.4          1.4         0.3  setosa
6           5.1         3.5          1.4         0.2  setosa
7           4.6         3.1          1.5         0.2  setosa
8           5.1         3.5          1.4         0.3  setosa
9           4.9         3.0          1.4         0.2  setosa
10          4.8         3.1          1.6         0.2  setosa
11          5.2         4.1          1.5         0.1  setosa
12          5.1         3.5          1.4         0.2  setosa
13          4.3         3.0          1.1         0.1  setosa
14          5.5         3.5          1.3         0.2  setosa
15          5.1         3.8          1.9         0.4  setosa

Upvotes: 2

ALiX
ALiX

Reputation: 1031

Just index properly into the matrix that is being assigned to. For example:

store <- matrix(0, nrow=15, ncol=5)
m <- matrix(1:25, nrow=5, ncol=5)
store[1:5, 1:5] <- m
store

      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    6   11   16   21
 [2,]    2    7   12   17   22
 [3,]    3    8   13   18   23
 [4,]    4    9   14   19   24
 [5,]    5   10   15   20   25
 [6,]    0    0    0    0    0
 [7,]    0    0    0    0    0
 [8,]    0    0    0    0    0
 [9,]    0    0    0    0    0
[10,]    0    0    0    0    0
[11,]    0    0    0    0    0
[12,]    0    0    0    0    0
[13,]    0    0    0    0    0
[14,]    0    0    0    0    0
[15,]    0    0    0    0    0

Upvotes: 0

Related Questions