[R] Embedding lists in matrices and matrices in lists

Petr PIKAL petr.pikal at precheza.cz
Thu Aug 20 08:39:03 CEST 2009


Hi


Michael Kogan <michael.kogan at gmx.net> napsal dne 19.08.2009 17:22:04:

> Thanks, that was the solution! But in fact I didn't want to have this 
> "list of lists" layer at all. And now I'm having trouble writing 
> matrices into the database.  It's really really strange... If I write a 
> matrix into the database manually everything works, but if I create a 
> function which adds a matrix into the database and then run the function 

> it fails... Look at this (sorry for the long code block, in fact you can 

> skip the "sums" and "test_sums" functions):
> > ######################test matrix#######################
> > m1=matrix(c(
> > 1,0,
> > 0,1
> > ),nrow=2, byrow=TRUE)
> >
> > #########################sums###########################
> > sums=function(matrix)
> > {
> > c(sort(colSums(matrix)),sort(rowSums(matrix)))
> > }
> >
> > ######################test_sums#########################
> > test_sums=function(matrix)
> > {
> > liste=database[[nrow(matrix),ncol(matrix)]][[1]]
> > w=1
> > if(length(liste)>0){
> >     for(i in 1:length(liste)){
> >         if(all(sums(matrix)==sums(liste[[i]]))){
> >             w0=0
> >         }else{
> >             w0=1}
> >     w=w*w0}
> > }else{
> >     w=2}
> > w
> > }
> >
> > #####################write to db########################
> > write_to_db=function(matrix){
> > en=nrow(matrix)
> > fn=ncol(matrix)
> > if(test_sums(matrix)==1){
> >     print("matrix isn't in the DB yet")
> >     database[en,fn][[1]]=list(database[en,fn][[1]], matrix)
> > }else if(test_sums(matrix)==2){
> >     print("matrix isn't in the DB entry yet and DB is empty")
> >     database[en,fn][[1]][[1]]=list(matrix)
> > }else{
> >     print("matrix already exists in the DB")
> > }
> > }
> >
> > ######################create database##################
> > database=matrix(list(),2,2)
> >
> > ##trying to write a matrix into db using the function##
> > write_to_db(m1)
> > database
> >
> > ###writing a matrix into db without using a function###
> > en=nrow(m1)
> > fn=ncol(m1)
> > if(test_sums(m1)==1){
> >     print("matrix isn't in the DB yet")
> >     database[en,fn][[1]]=list(database[en,fn][[1]], m1)
> > }else if(test_sums(m1)==2){
> >     print("matrix isn't in the DB entry yet and DB is empty")
> >     database[en,fn][[1]][[1]]=list(m1)
> > }else{
> >     print("matrix already exists in the DB")
> > }
> > database
> >
> > ###########test whether matrix already is in db##########
> > write_to_db(m1)
> And the output is:
> > [1] "matrix isn't in the DB entry yet and DB is empty"
> >      [,1] [,2]
> > [1,] NULL NULL
> > [2,] NULL NULL
> > [1] "matrix isn't in the DB entry yet and DB is empty"
> >      [,1] [,2] 
> > [1,] NULL NULL 
> > [2,] NULL List,1
> > [1] "matrix already exists in the DB"
> So writing the matrix into the database using the function fails while 
> writing it using the same commands but not through a function works! 
> Maybe it's a problem with all these layers in the database matrix?

No. It is the problem of scoping. AFAIK functions create their own 
environment and everything what is assigned inside the function does not 
affect outside objects unless you use <<- assignment operator. 

i<-100
ff<-function(x) i<-x
ff(10)
i
[1] 100
fff<-function(x) i<<-x
fff(200)
i
[1] 200

However I would distract you from this practice. Personally I used such 
assignment only when I started with S/R about 10 years ago.

Why do you want a database to be a matrix? It seems to be that list 
structure is in that case more flexible and there are *apply functions for 
manipulation with lists. E.g. structure lm(...) results in list and 
summary(lm(...)) is again a list with quite complicated structure.

If I understand it correctly, during your computation you will have as a 
result matrices with arbitrary dimensions.

I would make a list

lll<-vector("list", 1)

and in simple loop

for (i in 1:n) {

do any computation here together with sophisticated and complicated 
functions and assign results to your list

lll[[1]] <- result of functions which itself can have quite complicated 
structure

}

If you want nested list just add another cycle and use

lll[[i]][[j]] <-some other result.

With choosing appropriate structure of your date you can save yourself 
much problems.
Regards
Petr


>

> 
> Petr PIKAL schrieb:
> > Hi
> >
> > r-help-bounces at r-project.org napsal dne 19.08.2009 13:04:39:
> >
> > 
> >> Strange, it doesn't work for me:
> >>
> >> Error in database[4, 4][[1]][1, ] : incorrect number of dimensions
> >> Execution halted
> >>
> >> R version 2.9.0 (2009-04-17) on Arch Linux, no additional packages 
> >> installed.
> >> 
> >
> > database[4,4][[1]][,1]
> >
> > does not work for me either but it is result of your complicated 
structure 
> > of nested lists
> >
> > This works
> >
> > 
> >> database[4,4][[1]][[1]][,1]
> >> 
> > [1] 0 1 1 1
> >
> > See the structure
> >
> > Matrix of lists
> >
> > 
> >> database
> >> 
> >      [,1] [,2] [,3] [,4]   [,5]
> > [1,] NULL NULL NULL NULL   NULL
> > [2,] NULL NULL NULL NULL   NULL
> > [3,] NULL NULL NULL NULL   NULL
> > [4,] NULL NULL NULL List,1 NULL
> > [5,] NULL NULL NULL NULL   NULL
> >
> > List of lists
> > 
> >> database[4,4]
> >> 
> > [[1]]
> > [[1]][[1]]
> >      [,1] [,2] [,3] [,4]
> > [1,]    0    1    1    1
> > [2,]    1    0    1    1
> > [3,]    1    1    0    1
> > [4,]    1    1    1    0
> >
> > List which contains your matrix
> >
> > 
> >> database[4,4][[1]]
> >> 
> > [[1]]
> >      [,1] [,2] [,3] [,4]
> > [1,]    0    1    1    1
> > [2,]    1    0    1    1
> > [3,]    1    1    0    1
> > [4,]    1    1    1    0
> >
> > Here is your matrix
> >
> > 
> >> database[4,4][[1]][[1]]
> >> 
> >      [,1] [,2] [,3] [,4]
> > [1,]    0    1    1    1
> > [2,]    1    0    1    1
> > [3,]    1    1    0    1
> > [4,]    1    1    1    0
> > 
> >
> > Regards
> > Petr




More information about the R-help mailing list