How to save or reserve a list of objects? (R)

Asked

Viewed 4,318 times

2

In R, I’m wanting to "keep a list of matrices".

In fact, I’m wanting to reserve a list of 10 objects, where each object will turn into an array, after using a for()

Something like that:

Data <- uma base de dados

Lista <- é a lista que eu quero guardar ou reservar (criar?)

for(i in 1:10)
{

 Lista[i]<- subset(Data, coluna1 == levels(Coluna1)[i] )

}

Thus, List is a list of 10 matrices...

2 answers

2


Well, you can either store arrays in a list or an array.

With the array the idea would be to use a three-dimensional array. The third dimension would be an indexer of the matrices. However, for this solution, all matrices have to be equal in size.

For example, the command below generates an array that can be interpreted as follows: it stores 10 matrices 2 x 2.

matrizes <- array(dim= c(2,2,10))

Then you can popular this array by indexing in the third dimension:

set.seed(1)
for (i in 1:10){
  matrizes[,,i] <- matrix(rnorm(4), ncol=2)
}

Thus, to access the first matrix:

matrizes[,,1]
           [,1]       [,2]
[1,] -0.6264538 -0.8356286
[2,]  0.1836433  1.5952808

or the tenth matrix

matrizes[,,10]

           [,1]      [,2]
[1,] -0.3942900 1.1000254
[2,] -0.0593134 0.7631757

The other option is as you said yourself, to store in a list. Lists are very flexible in R, so if you want to store other objects together with the matrices, or if the matrices are of different sizes, the list is more suitable.

matrizes <- list()

set.seed(1)
for (i in 1:10){
  matrizes[[i]] <- matrix(rnorm(4), ncol=2)
}

Accessing the matrix 1:

matrizes[[1]]
          [,1]       [,2]
[1,] -0.6264538 -0.8356286
[2,]  0.1836433  1.5952808

And the matrix 10:

matrizes[[10]]
           [,1]      [,2]
[1,] -0.3942900 1.1000254
[2,] -0.0593134 0.7631757
  • In this case, as you can see in my code, I have no way to determine the dimensions of the matrices... they will be generated within the for() command.. The idea is that I reserve a list with 10 generic matrices and then replace each one with a matrix of a random dimension... I could even create a list with the 10 matrices of 4x2 and then try to replace, but gives 10 errors: In ucs_educ_niveis[i] <- subset(inf_ucs_com_criancas_em_escola_2, : number of items to replace is not a Multiple of Replacement length

  • 2

    @Vasco if the matrices are of different sizes then it has to be by list even, just run the loop as I put in the example, replacing the matrix(rnorm(4), ncol=2) at your command.

  • I get it... thank you

0

Vasco if I’m not wrong you have a typical task in which the most elegant solution is a split. The solution I’m going to present to you is for when you want to separate a data set relative to the levels of a factor. For example I will use the iris dataset:

## Carregando os dados
data(iris)

## Vendo as primeiras linhas
head(iris)

Note that the last column is the species. Let’s see how many species there are

## Mostrando os níveis de Species
levels(iris$Species)

Note that there are three: [1] "setosa" "versicolor" "virginica"

Now I’m going to separate the data.frame into three, creating a list, where each element in the list is a data.frame containing only the lines relative to the factor level specified in the split.

## Separando por espécie
lista <- split(x = iris, f = iris$Species)

Ready! Now I can apply any method in the separate parts. Suppose I want to average the variable Sepal.Length for each species:

## Média por espécie
lapply(lista, function(x) mean(x$Sepal.Length))

$setosa
[1] 5.006

$versicolor
[1] 5.936

$virginica
[1] 6.588

If it’s a simple function like the average, considering only one factor, there’s a much faster way with tapply:

## Média por espécie
tapply(iris$Sepal.Length, iris$Species, mean)

     setosa versicolor  virginica 
     5.006      5.936      6.588 

But note that the split solution is more general and applies to more complex situations involving operations with more than one column.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.