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 ) ;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.