I am trying to extract multiple items from a SAS/IML list. I have limited success using colvec() and rowvec() but when I try to simplify my code, I run into syntax errors that I do not understand. Here is my code:
proc iml ;
package load listutil ;
e = [ #'nobs' =3
, #'nvars'=2
, #'type' =[ 'N' ] || [ 'N' ]
, #'name' =[ 'var1' ] || [ 'var2' ]
, #'cols' =[{ 11 21 31 }] || [{ 12 22 32 }]
] ;
call listprint( e ) ;
columns = colvec( e$'cols'$1 ) || colvec( e$'cols'$2 ) ; /* this is awkward but "columns = e$'cols'$1 || e$'cols'$2" gives me a list and I want a numeric matrix */
print columns ;
colnames = rowvec( e$'name'$1 ) || rowvec( e$'name'$2 ) ; /* same reason as for columns, above */
print colnames ;
tbl = TableCreate( colnames, columns ) ; /* this code works, but getting to this point is inelegant, IMHO */
call TablePrint( tbl ) ;
sublist = [ 1:2 ] ;
a = e$'cols'$sublist ; /* is this the correct syntax? the SAS/IML interpreter thinks otherwise */
call listprint ( a ) ;
quit ;
I want to extract columns 1 and 2 from list item e$'cols' with one subsetting operation so I defined a sublist and tried to define list a, but failed. Where am I going wrong?
Your confusion is caused because the brackets ([...]) are used both for subscript operations and to define lists. If you want to extract the 1st and 2nd items in a list, use the subscript operator:
idx = 1:2;
a = e$'cols'[idx]; /* subscripts, not a list */
call listprint ( a ) ;
With regard to your meta-question ("extracting the data is inelegant"), I suggest that you might benefit by rethinking your data structure. Here are a few concrete suggestions:
The following program might give you some ideas to play with:
proc iml ;
package load listutil ;
/* if data are homogeneous, use a matrix instead of a list */
e = [ #'nobs' =3
, #'nvars'=3
, #'type' ={'N' 'N' 'N'}
, #'name' ={'var1' 'var2' 'var3'}
, #'cols' =[{ 11, 21, 31 }, { 12, 22, 32 }, {A, B, C}]
] ;
call struct( e ) ;
/* to create a table from names and columns, use TableAddVar */
varIdx = {1 3};
tbl = TableCreate();
do i = 1 to ncol(varIdx);
k = varIdx[i];
call TableAddVar(tbl, e$'name'[k], e$'cols'$k);
end;
call TablePrint( tbl ) ;
Thank you for calling my attention to the 'SAS/IML' forum and Rick Wicklin.
Your confusion is caused because the brackets ([...]) are used both for subscript operations and to define lists. If you want to extract the 1st and 2nd items in a list, use the subscript operator:
idx = 1:2;
a = e$'cols'[idx]; /* subscripts, not a list */
call listprint ( a ) ;
With regard to your meta-question ("extracting the data is inelegant"), I suggest that you might benefit by rethinking your data structure. Here are a few concrete suggestions:
The following program might give you some ideas to play with:
proc iml ;
package load listutil ;
/* if data are homogeneous, use a matrix instead of a list */
e = [ #'nobs' =3
, #'nvars'=3
, #'type' ={'N' 'N' 'N'}
, #'name' ={'var1' 'var2' 'var3'}
, #'cols' =[{ 11, 21, 31 }, { 12, 22, 32 }, {A, B, C}]
] ;
call struct( e ) ;
/* to create a table from names and columns, use TableAddVar */
varIdx = {1 3};
tbl = TableCreate();
do i = 1 to ncol(varIdx);
k = varIdx[i];
call TableAddVar(tbl, e$'name'[k], e$'cols'$k);
end;
call TablePrint( tbl ) ;
SAS is headed back to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team.
Interested in speaking? Content from our attendees is one of the reasons that makes SAS Innovate such a special event!
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.