- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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?
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
> 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;