BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
rbettinger
Pyrite | Level 9

MATLAB has structure syntax like

a.b( index ).c = d ;

where index is an integer.

How do I create an IML list equivalent to the MATLAB statement? This will be a hierarchical heterogeneous list, I think.

Given the first instance, e.g.,

a.b(1).c = d ;

if index is incremented, how do I tell IML to create the second instance,

a.b(2).c = e;

so that an array of sublists is created?

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

Not sure what people are asking, but maybe study this program and see if it helps to answer your questions. At least it provides a concrete example that we can discuss.

 

proc iml;
package load ListUtil;

/* create list of lists. 
   Specify L$1$1, L$1$2, L$2$1, and L$2$2 */
L = ListCreate(3);
L$1 = ListCreate(2);
L$1$1 = 'L11';
L$1$2 = 12;
L$2 = ListCreate(2);
L$2$1 = 'L21';
L$2$2 = 22;

/* Now add a third item to L$2 and access it as L$2$3 */
newVal = 23;
L2 = ListGetSubItem(L, 2, 'm');     /* get the sublist you want to expand */
call ListAddItem(L2, newVal);       /* expand it */
call ListSetSubItem(L, 2, L2, 'm'); /* set it back into the list */
call struct(L);

check = L$2$3;     /* make sure the new item exists */
print check;

View solution in original post

8 REPLIES 8
Rick_SAS
SAS Super FREQ

Please post a SAS/IML program that shows what you are trying to accomplish. Use the IML syntax, not the syntax from a different language.

 

As a general rule, use ListAddItem to add a new item to an existing list. If the item you add is a list, you can use ListAddItem to add items to that list, thus emulating a hierarchical structure.

 

IanWakeling
Barite | Level 11

Hi Rick,

Can you give an example of how you can use ListAddItem to extend a sublist?  I can make it work at the top level, but not lower down in the hierarchy.

Rick_SAS
SAS Super FREQ

Please show what you have tried.

 

Keep in mind that MATLAB data structures are more general than lists. The main purpose of the SAS/IML lists is to pack objects of various types into a single object that can be passed to and from modules. You might be able to coerce lists to emulate other data structures, but you will have to be clever. 

 

IanWakeling
Barite | Level 11

Here is an example.  If I create a list with 3 items where the second item is itself a list - like this:

L = [[1:3], [i(2),i(3)], [4:6]];

Then I might want to add i(4) to the sublist.   I have tried syntax like:

Call ListAddItem(L$2, i(4));

but this, and using L[2] instead of L$2, both leave L unmodified. If by being clever you mean something like:

  L$2 = [ L$2 || [i(4)] ];

then this works but essentially I have just manually reconstructed L$2.  It feels like there should be a subroutine called ListAddSubItem to do what I want, but it is not there.

rbettinger
Pyrite | Level 9

I thank all of you for your interest in my question and for your suggestions.

 

I am trying to create a SAS/IML list with the following structure:

a$1$c = 'item 1'

a$2$c = 'item 2'

a$3$c = 'item 3'

b$1$c = 'item 1'

b$2$c = 'item 2'

b$3$c = 'item 3'

b$4$c = 'item 4'

...

After studying Dr. Wicklin's example, I think that this code does the task:

-----------

proc iml ; package load listutil ;
L = [] ;
do i = 1 to 2 ;
call ListAddItem( L, [ #type='input', i, #item='item' + char(i) ] ) ;
end ;
do i = 1 to 3 ;
call ListAddItem( L, [ #type='output', i, #item='item' + char(i) ] ) ;
end ;
call struct( L ) ;
quit ;

----------

How can I produce the same result using the list syntax "$" instead of "ListAddItem" ?

Ross

Rick_SAS
SAS Super FREQ

Not sure what people are asking, but maybe study this program and see if it helps to answer your questions. At least it provides a concrete example that we can discuss.

 

proc iml;
package load ListUtil;

/* create list of lists. 
   Specify L$1$1, L$1$2, L$2$1, and L$2$2 */
L = ListCreate(3);
L$1 = ListCreate(2);
L$1$1 = 'L11';
L$1$2 = 12;
L$2 = ListCreate(2);
L$2$1 = 'L21';
L$2$2 = 22;

/* Now add a third item to L$2 and access it as L$2$3 */
newVal = 23;
L2 = ListGetSubItem(L, 2, 'm');     /* get the sublist you want to expand */
call ListAddItem(L2, newVal);       /* expand it */
call ListSetSubItem(L, 2, L2, 'm'); /* set it back into the list */
call struct(L);

check = L$2$3;     /* make sure the new item exists */
print check;

IanWakeling
Barite | Level 11

Thank you Rick, I see how to do it now.  So following your example I could make my own version of ListAddSubItem as follows:

proc iml;

start ListAddSubItem(A, Pos, Val);
  if type(A) ^= 'L' then return;
  B = ListGetSubItem(A, Pos, 'm');
  if type(B) = 'L' then call ListAddItem(B, Val);
  call ListSetSubItem(A, Pos, B, 'm');
finish;

package load listutil;

L = [ 2, [5, 6], 9 ];
call ListAddSubItem(L, 2, 7);
call struct(L);
quit;
Rick_SAS
SAS Super FREQ

> How can I produce the same result using the list syntax "$" instead of "ListAddItem" ?

 

You can't, unless you use concatenation as Ian showed earlier. The '$' syntax refers to an item that already exists. The ListAddItem function creates a new item in the list. 

 

Think of the $ operator as analogous to subscripts for matrices. If you define
m = 11:13;

you cannot reference m[4] because that element does not exist. If you want to add a new item to the m matrix, you need to use concatenation or "allocate and copy":

m1 = m || {14};
or

m2 = j(1, ncol(m)+1, .);
m2[1:3] = m;
m2[4] = 14;

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 8 replies
  • 677 views
  • 8 likes
  • 3 in conversation