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

Hello,

I inherited a large set of SAS programs and macros that I need to use to calculate a number of indices on environmental data.  I think the programs and macros were developed under SAS v7.  I currently have v9.4, with IML v14.3, operating under Windows 64-bit.  My SAS programming ability is limited and rusty, and I've had no prior experience with IML.  The code I inherited calls macros within macros within macros to do such things as variable name manipulation.

 

The point at which I'm stuck right now is a macro which invokes IML, using other macros to generate the dataset and variable names.

 

I apologize in advance for the long post -- it shows the errors I get with multiple different attempts at modifying the code.  Help will be appreciated!  Thank you.

 

The original code (which does not work) in the calling macro was:

 

PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE &dsn VAR%imlvar(&var);
 READ ALL INTO X;

 

where the dsn name was provided by an earlier call to a different macro and imlvar is another macro, which takes the var variable (provided by an earlier call to yet another macro) and creates a list of indexed variables from other variables, as follows:

 

%let vari=("%substr(&var,1,%eval(&i-1))":"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))");

 

The value of vari returned is ("s1":"s814").  (Yes, there are 814 numeric fields in this dataset, in addition to numerous other fields.)

 

The log shows:

MPRINT(TSALL):   USE ridsn_
NOTE: Line generated by the invoked macro "IMLVAR".
1    *
     -
     79
ERROR 79-322: Expecting a {.

MPRINT(IMLVAR):   VAR* * ( "s1":
MPRINT(TSALL):  "s814");
NOTE: Line generated by the macro variable "VARI".
1      ("s1":"s814")
            -
            22
            200
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant,
              a datetime constant, a missing value, (, (|, ), *, ',', -, =, [, |, }.

ERROR 200-322: The symbol is not recognized and will be ignored.

MPRINT(TSALL):   READ ALL INTO X;
ERROR: No data set is currently open for input.

- - - - - - - - - - - - - - - - - - - - - - - -
After reading up on IML and changing just one thing at a time, I have modified the code (which still doesn't work) numerous times, some of which follow:

 

With:
PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE (&dsn) VAR{%imlvar(&var)};
 READ ALL INTO X;
and
%let vari="%substr(&var,1,%eval(&i-1))":"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))";

 

the errors are:

MPRINT(TSALL):   USE (ridsn_) VAR{
MPRINT(IMLVAR):  * "s1":
NOTE: Line generated by the macro variable "VARI".
1      "s1":"s814"
           -
           22
           200
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant,
              a datetime constant, a missing value, (, (|, ), *, ',', -, =, [, |, }.

ERROR 200-322: The symbol is not recognized and will be ignored.

MPRINT(TSALL):  "s814"} READ ALL INTO X;
ERROR: No data set is currently open for input.

- - - - - - - - - - - - - - - - - - - - - - - -
With:
PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE (&dsn) VAR(%imlvar(&var));
 READ ALL INTO X;
and
%let vari={"%substr(&var,1,%eval(&i-1))":"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))"};

 

the errors are:

MPRINT(TSALL):   USE (ridsn_) VAR(
NOTE: Line generated by the invoked macro "IMLVAR".
1    *
     -
     79
ERROR 79-322: Expecting a {.

MPRINT(IMLVAR):  * * ( "s1":
NOTE 137-205: Line generated by the invoked macro "TSALL".
3      PROC IML;   RESET NONAME;   ERRFLAG=0;  USE (&dsn) VAR(%imlvar(&var));  READ ALL INTO X;   RESET LOG;
                                                                           -
                                                                           22
ERROR 22-322: Syntax error, expecting one of the following: ;, NOBS, VAR, VARIABLES, WHERE.

NOTE: Line generated by the invoked macro "TSALL".
3      PROC IML;   RESET NONAME;   ERRFLAG=0;  USE (&dsn) VAR(%imlvar(&var));  READ ALL INTO X;   RESET LOG;
                                                                           -
                                                                           200
ERROR 200-322: The symbol is not recognized and will be ignored.

NOTE: Line generated by the macro variable "VARI".
1      ("s1":"s814")
            -
            79
ERROR 79-322: Expecting a }.

MPRINT(TSALL):  "s814") ) READ ALL INTO X;
ERROR: No data set is currently open for input.

- - - - - - - - - - - - - - - - - - - - - - - -
With:
PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE (&dsn) VAR{%imlvar(&var)};
 READ ALL INTO X;
and
%let vari="%substr(&var,1,%eval(&i-1))":"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))";

 

the errors are:

MPRINT(TSALL):   USE (ridsn_) VAR{
MPRINT(IMLVAR):  * * ("s1":
MPRINT(TSALL):  "s814")};
NOTE: Line generated by the macro variable "VARI".
1      ("s1":"s814")
            -
            22
            200
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant,
              a datetime constant, a missing value, (, (|, ), *, ',', -, =, [, |, }.

ERROR 200-322: The symbol is not recognized and will be ignored.

MPRINT(TSALL):   READ ALL INTO X;
ERROR: No data set is currently open for input.

 statement : READ at line 2922 column 75

- - - - - - - - - - - - - - - - - - - - - - - -
With:
PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE (&dsn);
 READ ALL VAR{%imlvar(&var)} INTO X;
and
%let vari="%substr(&var,1,%eval(&i-1))":"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))";

 

the errors are:

MPRINT(TSALL):   USE (ridsn_);
ERROR: No input file specified.

 statement : USE at line 2922 column 43
NOTE: Exiting IML.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE IML used (Total process time):
      real time           0.97 seconds
      cpu time            0.75 seconds

MPRINT(TSALL):   READ ALL VAR{
MPRINT(IMLVAR):  * * ("s1":"s814")
MPRINT(TSALL):  } INTO X;

- - - - - - - - - - - - - - - - - - - - - - - -
With:
PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE &dsn;
 READ ALL VAR{%imlvar(&var)} INTO X;
and
%let vari="%substr(&var,1,%eval(&i-1))":"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))";

 

the errors are:

MPRINT(TSALL):   USE ridsn_;
MPRINT(TSALL):   READ ALL VAR{
MPRINT(IMLVAR):  * * ("s1":
MPRINT(TSALL):  "s814")} INTO X;
NOTE: Line generated by the macro variable "VARI".
1      ("s1":"s814")
            -
            22
            200
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant,
              a datetime constant, a missing value, (, (|, ), *, ',', -, =, [, |, }.

ERROR 200-322: The symbol is not recognized and will be ignored.

- - - - - - - - - - - - - - - - - - - - - - - -
With:
PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE &dsn;
 READ ALL VAR %imlvar(&var) INTO X;
and
%let vari="%substr(&var,1,%eval(&i-1))":"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))";

 

the errors are:

MPRINT(TSALL):   USE ridsn_;
MPRINT(TSALL):   READ ALL VAR
NOTE: Line generated by the invoked macro "IMLVAR".
1     *
      -
      79
ERROR 79-322: Expecting a {.

MPRINT(IMLVAR):   * * ( "s1":
MPRINT(TSALL):  "s814") INTO X;
NOTE: Line generated by the invoked macro "TSALL".
3      PROC IML;   RESET NONAME;   ERRFLAG=0;  USE &dsn;  READ ALL VAR %imlvar(&var) INTO X;   RESET LOG;
                                                                                           -
                                                                                           79
ERROR 79-322: Expecting a }.

NOTE: Line generated by the macro variable "VARI".
1      ("s1":"s814")
            -
            22
            200
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant,
              a datetime constant, a missing value, (, (|, ), *, ',', -, =, [, |, }.

ERROR 200-322: The symbol is not recognized and will be ignored.

- - - - - - - - - - - - - - - - - - - - - - - -
With:

PROC IML;
 RESET NONAME;
 ERRFLAG=0;
 USE &dsn;
 READ ALL VAR{%imlvar(&var)} INTO X;
and
%let vari="%substr(&var,1,%eval(&i-1))"-"%substr(&var,%eval(&i+1),%eval(%length(&var)-&i))";


the errors are:

MPRINT(TSALL):   USE ridsn_;
MPRINT(TSALL):   READ ALL VAR{
MPRINT(IMLVAR):  * * * "s1"-"s814"
MPRINT(TSALL):  } INTO X;
NOTE: Line generated by the macro variable "VARI".
1      "s1"-"s814"
            ------
            22
            76
ERROR 22-322: Syntax error, expecting one of the following: a numeric constant, a datetime constant, a missing value.

ERROR 76-322: Syntax error, statement will be ignored.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
IanWakeling
Barite | Level 11

You can't use the colon inside a character literal.   So the correct way is to use ordinary round braces (parentheses):

 

READ ALL VAR ("s1":"s814") INTO X;

 

View solution in original post

10 REPLIES 10
VPartridge
Calcite | Level 5

To clarify, since the font in the post doesn't show how the errors line up with the code:  All of the 22-322 errors except the last one were about the colon separating the indexed variables.

ballardw
Super User

@VPartridge wrote:

To clarify, since the font in the post doesn't show how the errors line up with the code:  All of the 22-322 errors except the last one were about the colon separating the indexed variables.


Post code and log results into a code window. Copy them from your editor or the SAS log. Then open a code box using the {I} icon and paste.

You will also see the results in a box:

proc sgplot data=collegesurvey;
  vbar gradelevel /group=planstogotocollege groupdisplay=cluster;
run;

The icon that looks like the "running man" next to the {I} also opens a code box that supports some code highlighting and will also preserve spaces better.

 

The main message windows on this forum apparently hate multiple spaces, tabs or other white-space characters and will combine multiples into singles.  

VPartridge
Calcite | Level 5

Thanks for the tip on how to post code and logs.

VPartridge
Calcite | Level 5

When I dispense with trying to generate the variable list from the IMLVAR macro and just use

USE &dsn;
 READ ALL VAR {"s1":"s814"} INTO X;

in the calling program (with or without the curly braces), I still get the 22-322 error complaining about the colon.

 

Tom
Super User Tom
Super User

@VPartridge wrote:

When I dispense with trying to generate the variable list from the IMLVAR macro and just use

USE &dsn;
 READ ALL VAR {"s1":"s814"} INTO X;

in the calling program (with or without the curly braces), I still get the 22-322 error complaining about the colon.

 


What is it that you think the colon is doing?  If you are trying to specify column or row names don't you need to add the colname= or rowname= keyword to the read statement?

IanWakeling
Barite | Level 11

You can't use the colon inside a character literal.   So the correct way is to use ordinary round braces (parentheses):

 

READ ALL VAR ("s1":"s814") INTO X;

 

VPartridge
Calcite | Level 5

Thank you, Ian.  That worked.  (That was about the only combination I hadn't tried!)

Tom
Super User Tom
Super User

I see two thing that you probably want to fix. One is the IML syntax for specifying a list of variables names using string literals (as apposed to an IML vector of names).  For that you need to use normal parentheses.

So you can use the IML VAR option on the USE or READ statement. Or you could use the normal SAS syntax for variable ranges if you use the KEEP= dataset option when specifying the source dataset on the USE statement.

data x;
  input s1-s5 ;
cards;
1 2 3 4 5
6 7 8 9 10
;

proc iml ;
use work.x ;
read all var ("s2":"s4") into x;
print x;

use work.x var ("s2":"s4");
read all into y;
print y;

use work.x(keep=s2-s4) ;
read all into z;
print z;

quit;

Second is it looks like your %IMLVAR() macro is emitted some extra garbage.

From the things you did post it looks like the macro is generating extra * characters.

MPRINT(TSALL):   USE (ridsn_) VAR{
MPRINT(IMLVAR):  * "s1":

that are causing trouble.

When you are defining this type of "command" or in-line macro make sure that the only non-macro statements are the text that you want the macro to emit.

Say you want to define macro that will take a base name and start and stop index number and have it generate the IML syntax needed.

For example you might make a macro like this to emit a variable list in IML format with the quotes and the colon.

%macro imlvar(base,start,stop);
"&base.&start":"&base.&stop"
%mend;

You could then use it in your IML code like this:

read all var (%imlvar(s,2,4)) into x;

 

VPartridge
Calcite | Level 5

Thank you, Tom.  And thanks also for editing my original post so that it's readable!

VPartridge
Calcite | Level 5

Whoops!  Thanks to Rick for editing my original post!

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

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
  • 10 replies
  • 1690 views
  • 2 likes
  • 4 in conversation