[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