9

What i want to have is a matrix in which each element is a list itself. See the following example:

1       2       3
1  1,2,4  1,2      1
2  Null   3,4,5,6  1,3  

I saw this post, and tried the following but got an error :

 b <- array()
 b[j, i, ] <- A[i]

where A is a vector itself. The error was:

 Error in b[j, i, ] <- A[i] : incorrect number of subscripts

How should I define and access each element of the matrix and each element of the contained lists?

Update1 :

b<-matrix(list(),nrow = length(d), ncol =length(c))

Error in b[j, i] <- A[i] : replacement has length zero

I want to specify that each element is a list and then try to fill it with various list with different length from zero to n.

Update2 :

 running what @BondedDust commented :
 b<-matrix(rep(list(),(c*d)),,nrow = length(d), ncol =length(c))
 Erorr in b[[j*nrow(b)+i]] <- A[i] : attempt to select less than one element

A :

A[1]<-c(3)     F[[1]]<-numeric(0)   E[[1]]<-numeric(0)
A[2]<-c(1)     F[2]<-c(1)           E[2]<-c(1)
A[3]<-c(1)     F[3]<-c(2)           E[[3]]<-numeric(0)
A[[4]]<-c(1,3) F[[4]]<-numeric(0)   E[[4]]<-numeric(0)
A[5]<-c(4)     F[5]<-c(4)           E[5]<-c(4)

A :values of row 1 , F:row 2 and E :row 3. ( 5 column )

this data is not in this form and is not stored any where,they are the output of another function (there is function in the place of A[i]).the data just show what dose A look likes reproducibly and therefore shows the position in the matrix and gives back the error in update2.A[4] is the element of column 4 row 2.

Community
  • 1
  • 1
academic.user
  • 609
  • 2
  • 7
  • 24
  • @DavidArenburg isn't `matrix(list(c(1,2,3)))` what he needs? – Molx May 02 '15 at 22:00
  • 1
    It is _not_ impossible to have list elements in matrices. – IRTFM May 02 '15 at 22:02
  • The documentation for `matrix` does not say that only atomic vectors can be given as arguments to the data parameter. It only says that `as.vector` will remove attributes. (Which strips Dates, POSIXct, and factor arguments of their classes.) If they are just lists (which are after all another form of "R vectors"), then there is no violence to the data. – IRTFM May 02 '15 at 22:21
  • To the edit. Setting an object as an empty array does not allow you to have dynamic array dimensioning. That may be a feature of arrays in other languages but NOT in R. – IRTFM May 02 '15 at 22:26
  • The task would have been easier if you had actually tested that code. See my edit. (It's not possible to do `E[1] – IRTFM May 03 '15 at 01:42
  • 1
    Furthermore, as I explained before, R matrices are indexed in _column_- _major_ _order_. I suppose you can always use the `t()` function is if absolution needs to be as you described. – IRTFM May 03 '15 at 01:49
  • @BondedDust,sorry for not checking it. I create list of list of list my self for this task but I prefer to have defined matrix to avoid creating list by adding rows and to have a general form , the data included was a data which reproduce the update2 error.(I included further explanation and correct the mistakes) but thanks for all your helps.the desired answer would be your comment(update2) (defining row and column or in the exact format you explained) without the error. – academic.user May 03 '15 at 11:04

1 Answers1

17

This builds that matrix although the print method does not display it in the manner you imagined:

 matrix( list(c(1,2,4), c(NULL), c(1,2), c(3,4,5,6), c(1), c(1,3)), 2,3)
 #---------
     [,1]      [,2]      [,3]     
[1,] Numeric,3 Numeric,2 1        
[2,] NULL      Numeric,4 Numeric,2

Inspect the first element:

> Mlist <- matrix( list(c(1,2,4), c(NULL), c(1,2), c(3,4,5,6), c(1), c(1,3)), 2,3)
> Mlist[1,1]
[[1]]
[1] 1 2 4

> is.matrix(Mlist)
[1] TRUE
> class( Mlist[1,1] )
[1] "list"

Demonstration of creating "matrix of lists" from a list:

> will.become.a.matrix <- list(c(1,2,4), c(NULL), c(1,2), c(3,4,5,6), c(1), c(1,3))
> is.matrix(will.become.a.matrix)
[1] FALSE
> dim(will.become.a.matrix) <- c(2,3)
> is.matrix(will.become.a.matrix)
[1] TRUE
> dim(will.become.a.matrix)
[1] 2 3
> class(will.become.a.matrix[1,1])
[1] "list"

Further requested demonstration:

 A<- list(); F=list() E=list()
 A[1]<-c(3) ;  F[[1]]<-numeric(0);  E[[1]]<-numeric(0)
 A[2]<-c(1) ;  F[2]<-c(1)   ;        E[2]<-c(1)
 A[3]<-c(1) ;  F[3]<-c(2)  ;         E[[3]]<-numeric(0)
 A[[4]]<-list(1,3) ;F[[4]]<-numeric(0) ; E[[4]]<-numeric(0)
 A[5]<-c(4) ; F[5]<-c(4)       ;    E[5]<-c(4)
 Mlist= c(A,F,E)
 M <- matrix(Mlist, length(A), 3)
#=====================================
> M
     [,1]   [,2]      [,3]     
[1,] 3      Numeric,0 Numeric,0
[2,] 1      1         1        
[3,] 1      2         Numeric,0
[4,] List,2 Numeric,0 Numeric,0
[5,] 4      4         4        

You asked (in comments) "....is there a way to define number of column and rows , but not the element itself because they are unknown?"

Answered (initially in comments)

b<-matrix(rep(list(), 6),nrow = 2, ncol =3) 
#.... then replace the NULL items with values. 
# Need to use "[[": for assignment (which your 'Update 1' did not 
# ....and your Update2 only did for some but not all of the assignments.)

b[[1]] <- c(1,2,3,4) 
IRTFM
  • 251,731
  • 20
  • 347
  • 472
  • thanks for your answer, the length of each element is unknown and it is much more bigger than this example, and I try to fill this in a loop, what is known is just the length of row an column which is itself based on other variables. – academic.user May 02 '15 at 22:04
  • While this does create the desired matrix, the entries of the matrix aren't lists but rather atomic vectors, as indicated by David Arenburg. – jhin May 02 '15 at 22:06
  • 1
    @jhin: I don't see how you can maintain that incorrect position after I showed you that the first element was a list. – IRTFM May 02 '15 at 22:08
  • @BondedDust, How to generalized it, define the structure first then access to each element to fill it ? – academic.user May 02 '15 at 22:13
  • @BondedDust You're right, sorry. I thought that list was just due to indexing. This is really weird! It creates a list with a single element for each matrix entry...? By the way, the fact that there are really list elements in the matrix might become more obvious if you included, e.g., `list("blah", 1)` as an element in your list, because then printing the matrix directly displays a "list" element. – jhin May 02 '15 at 22:15
  • 1
    Create a list with as many elements as needed. Make sure that the elements are arranged in "column-major order" and then assign a dimension of m x n using `dim – IRTFM May 02 '15 at 22:15
  • sorry, I didn't get it , would you please clarify it in your answer by an example? – academic.user May 02 '15 at 22:18
  • Here's a very ugly way to print the matrix with all elements (except `NULL` which becomes empty): `apply(m, c(1,2), function(x) paste(eval(parse(text=x)), collapse = " "))`. Is there any better approach to do it? – Molx May 02 '15 at 22:21
  • 1
    It is a common occurrence to get a matrix or array of lists from `tapply` when the value returned by the function argument is a list. – IRTFM May 02 '15 at 22:24
  • Thanks for the answer again @BondedDust, please see the update is there a way to define number of column and rows , but not the element itself because they are unknown,there was no problem with the definition but with the assignments. – academic.user May 02 '15 at 22:38
  • @BondedDust elements are not known at this step they are calculated by a function so I can not create the list as you suggested. and then create the matrix.I want to define this matrix type then access to each element to fill it. – academic.user May 02 '15 at 22:46
  • 1
  • thanks, I define it like `b – academic.user May 02 '15 at 22:54
  • 2
    As I said... need to use "[[": `b[[ j*nrow(b)+i]]` – IRTFM May 02 '15 at 22:54
  • thank you so much,but, this way I will access to each element t by its number, and not by the index of row and column,is there any other way? – academic.user May 02 '15 at 22:58
  • I am still not succeeded, this will gives me this error :`attempt to select less than one element`, please see the update2 – academic.user May 02 '15 at 23:21
  • If you do not post what `A` is (reproducibly) there is not hope for useful comment. – IRTFM May 03 '15 at 00:03
  • I couldn't provide the exact function which reproduce A as it depends on lots of other things. but a small output of it would be the one I included in the question,thank you – academic.user May 03 '15 at 01:06