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

I am trying to understand how IML creates a list that can be described as a matrix.

The documentation refers to item position in many List* commands and I can visualize a list as a linear array of items, addressable by scalars, e.g., L$1, L$2, L$3. But when there is more than one level to a list, e.g.,

 

proc iml ; package load ListUtil ;
L = [ #L1=[#L1_1=[#L1_2='Terminal Node']]
    , #L2=[ #L2_1='Terminal Node']
    , #L3=[#L3_1=[#L3_2=[#L3_3=[#L3_4='Terminal Node']]]]
    ] ;
call struct(L) ;
quit ;

then I do not understand how to specify the position of an item, e.g., L$L3$L3_1$L3_2$L3_3$L3_4 .

Please help me to understand the specification of an item's position in a complex list.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

Great. Glad to hear!

 

I'll mention further that if all the elements are named items, it is simpler (and more efficient) to pass a character array (rather thana list) as the last argument to the GetListSubItem function:

TermNode = ListGetSubItem( L, {'L3', 'L3_1', 'L3_2', 'L3_3', 'L3_4'}) ;

or even 

TermNode = ListGetSubItem( L, {L3 L3_1 L3_2 L3_3 L3_4}) ;

View solution in original post

4 REPLIES 4
Rick_SAS
SAS Super FREQ

Although your example of defining a named list works, it is a shorthand for the more correct definition

L = [ #'L1'=[#'L1_1'=[#'L1_2'='Terminal Node']], ... ];

 Names are character strings, so to retrieve the index you want, specify the list names as follows:

M = L$'L3'$'L3_1'$'L3_2'$'L3_3'$'L3_4';

 

rbettinger
Pyrite | Level 9
Your reply seems to have released a mental block. I referred to the
LISTGETSUBITEM documentation and saw the example where
M2=ListGetSubItem(L, ["A",2] ) ;

Then I applied the example to my question and show the result below:

proc iml ; package load ListUtil ;
L = [ #'L1'=[#'L1_1'=[#'L1_2'='Terminal Node']]
, #'L2'=[ #'L2_1'='Terminal Node']
, #'L3'=[#'L3_1'=[#'L3_2'=[#'L3_3'=[#'L3_4'='Terminal Node']]]]
] ;
call struct(L) ;
L_3_1_2_3_4 = L$'L3'$'L3_1'$'L3_2'$'L3_3'$'L3_4' ;
call struct( L_3_1_2_3_4 ) ;
call struct( L$'L3'$'L3_1'$'L3_2'$'L3_3'$'L3_4' ) ;
TermNode = ListGetSubItem( L, [ 'L3', 'L3_1', 'L3_2', 'L3_3', 'L3_4' ]) ;
print TermNode ;
quit ;

Now I can proceed. Thanks once again, Rick!
Rick_SAS
SAS Super FREQ

Great. Glad to hear!

 

I'll mention further that if all the elements are named items, it is simpler (and more efficient) to pass a character array (rather thana list) as the last argument to the GetListSubItem function:

TermNode = ListGetSubItem( L, {'L3', 'L3_1', 'L3_2', 'L3_3', 'L3_4'}) ;

or even 

TermNode = ListGetSubItem( L, {L3 L3_1 L3_2 L3_3 L3_4}) ;

rbettinger
Pyrite | Level 9

Continuing the conversation re: representing an IML list structure as a matrix, how do I determine the position of the item L3_4 in the following example:

proc iml ; package load ListUtil ;
L = [ #'L1'=[ #'L1_1' = [ #'L1_2' = 'item L1_2' ] ]
    , #'L2'=[ #'L2_1' = 'item L2_1']
    , #'L3'=[ #'L3_1 '= [ #'L3_2' = [ #'L3_3' = [ #'L3_4'= 'item L3_4' ] ] ] ]
    ] ;
call struct(L) ;
call listprint( L ) ;
quit ;

If I want to delete item L$'L3'$'L3_1'$'L3_2'$'L3_3'$'L3_4', how do I use ListDeleteItem() to do this? How do I represent the position as a numeric matrix of indices or a character matrix of item names? Is my confusion due to the fact that I am trying to delete an item from a sublist? If so, how do I delete an item from a sublist?

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

Register now

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 4 replies
  • 1223 views
  • 1 like
  • 2 in conversation