Kinin
Kinin

Reputation: 55

R programming:How to use loop on variables labelled in a consecutive manner?

I'm trying to figure out, how I can run a loop on some variables that have a consecutive label.

I want to do matrix.2-Matrix.1 and store it in matrix x.1, then Matrix.3-matrix.2 and store it in matrix x.2. There are 300 matrices(Matrix.1,Matrix.2,...Matrix.300) but for this example, I would like to just work on matrix 1,2 and 3.

I first tried an approach that involved the list function, but it didn't work, and then I thought about using a MACRO just like in SAS (the % symbol). But the Macro approach seemed not to work in R.

My code is below: (The list approach)

> Matrix.1=matrix(c(1:6),nrow=2,ncol=3,byrow=TRUE)
> Matrix.2=matrix(c(1,8,9,17,15,2),nrow=2,ncol=3,byrow=TRUE)
> Matrix.3=matrix(c(0,1,2,3,6,0),nrow=2,ncol=3,byrow=TRUE)
> x.1=matrix(rep(0,6),nrow=2,ncol=3,byrow=TRUE)
> x.2=matrix(rep(0,6),nrow=2,ncol=3,byrow=TRUE)
> m=list(Matrix.1=Matrix.1,Matrix.2=Matrix.2,Matrix.3=Matrix.3)
> x=list(x.1=x.1,x.2=x.2)
> m[1]
$Matrix.1
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
> m[2]
$Matrix.2
     [,1] [,2] [,3]
[1,]    1    8    9
[2,]   17   15    2
> m[3]
$Matrix.3
     [,1] [,2] [,3]
[1,]    0    1    2
[2,]    3    6    0
> x[1]
$x.1
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0

> x[2]
$x.2
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    0    0    0

> for (i in 1:2){
+ x[i]=m[i+1]-m[i]
+ print(x[i])
+ }
Error in m[i + 1] - m[i] : non-numeric argument to binary operator
> 

How can I make operations on list?

> #Other approach inspired from SAS
> for (i in i:2){
+ x.i=Matrix.i+1-Matrix.i
+ print(R.i)
+ }
Error: object 'Matrix.i' not found

This second approach isn't even doable in R.

What is the best way of dealing loops involving consecutively labelled variables?

Upvotes: 0

Views: 149

Answers (2)

lmo
lmo

Reputation: 38520

It is the preferred method in R to use the apply family of functions to loop through objects. For lists, you can use lapply which returns a list, or sapply which returns the most simplified object it can without losing any information. With these functions, you output is stored in the same order as the input, which makes comparisons or additional steps much easier.

myProcessedList <- lapply(x, FUN=<some function>)

This is a lot simpler and more straightforward than using assign and get and is worth the investment to learn. SO has many useful examples.

Upvotes: 0

JACKY88
JACKY88

Reputation: 3557

Since m and x are both lists, you need to use m[[1]] and x[[1]] to extract its elements.

for (i in 1:2){
  x[[i]] <- m[[i+1]]-m[[i]]
  print(x[[i]])
}

On the other hand, if you have 300 matrices (Matrix.1, Matrix.2, ... Matrix.300), you could use get and assign to deal with the numerical labels. Here I first assign values to 300 matrices with names Matrix.1 through Matrix.300. Then I use get function to extract these matrices and generate list x.

for (i in 1:300) {
  assign(paste("Matrix.", i, sep = ""), matrix(rnorm(9), 3, 3))
}

x <- list()
for (i in 2:300) {
  x[[i-1]] <- get(paste("Matrix.", i, sep = "")) - get(paste("Matrix.", i-1, sep = ""))
}

Upvotes: 1

Related Questions