zuluk
zuluk

Reputation: 1577

SAS include code into data step

I have dynamically create a myfile.sas with following content:

and a = 0
and b = 0

Now I want to include this file into a data step:

data y;
   set x;

   if 1=1 
      %include incl("myfile.sas")
   then selektion=0;
   else selektion=1;
run;

The result should be:

data y;
   set x;

   if 1=1 
      and a=0
      and b=0
   then myvar=0
   else myvar=1;
run;

However I get the following error:

ERROR 388-185: Expecting an arithmetic operator.
ERROR 200-322: The symbol is not recognized and will be ignored.

Is this possible to include the file into the if statement?

Upvotes: 1

Views: 4594

Answers (4)

Leonid Batkhan
Leonid Batkhan

Reputation: 101

As prior comments stated %include cannot be used inside other SAS statements. That is because %include in NOT a SAS macro, but rather SAS global statement. Global statements may only be used between other SAS statement, or as the very first and last statement in a SAS program.

While one cannot use %include for the stated purpose, I wrote a SAS macro function, called %embed() that can do just that. You can find %embed macro function definition and usage examples in my blog Embedding any code anywhere into SAS programs.

Upvotes: 0

Richard
Richard

Reputation: 27508

According to SAS documentation:

%INCLUDE Statement

Brings a SAS programming statement, data lines, or both, into a current SAS program.

The injection you are attempting is not a complete statement, so it fails. A more specific description of the action you are describing would be %INLINE. However, there is no such SAS statement.

Let's call a program that outputs code a 'codegener' and the output it produces the 'codegen'

In the context of your use the codegen is specific to a single statement. This highly suggests the codegener should be placing the codegen in a macro variable (for ease of later use) instead of a file.

Suppose the codegener uses data about statement construction:

DATA statements_meta;
  length varname $32 operator $10 value $200;
  input varname operator value;
  datalines;
a = 0
b = 0
run;

and the codegener is a DATA step

DATA _null_;
  file "myfile.snippet";
  ... looping logic over data for statement construction ...
    put " and " varname " = 0 "
  ...
run;

Change the codegener to be more like the following:

DATA _null_;
  length snippet $32000;
  snippet = "";
  ... looping logic over data for statement construction ...
    snippet = catx (" ", snippet, "and", varname, comparisonOperator, comparisonValue);
  ... end loop
  call symput('snippet', trim(snippet));
  stop;
run;
...
DATA ...
  if 1=1 &snippet then ... else ...
run;

Upvotes: 1

user2877959
user2877959

Reputation: 1792

Indeed, that doesn't work. You can use %include within a data or proc step to add some lines to it but not within an incomplete statement.

Had your myfile.sas looked like this:

if 1=1
and a = 0
and b = 0

you could have written

data y;
   set x;
   %include "myfile.sas";;
   then selektion=0;
   else selektion=1;
run;

Couldn't you have these lines in a macro instead of a file?

%macro mymacro;
  and a=0
  and b=0
%mend;

data y;
   set x;
   if 1=1 
      %mymacro
   then selektion=0;
   else selektion=1;
run;

If that myfile.sas has to stay as is, you could work around it in this rather convoluted (but still generic) way:

filename myfile temp;

data _null_;
file myfile2;
infile 'myfile.sas' eof=end;
input;
if _n_=1 then put '%macro mymacro;';
put _infile_;
return;
end:
  put '%mend;';
run;
%include myfile;

data y;
   set x;
   if 1=1 
      %mymacro
   then selektion=0;
   else selektion=1;
run;

Upvotes: 3

Tom
Tom

Reputation: 51566

The %INCLUDE needs to be at statement boundary. You could put the IF 1=1 into the same file or into another file. Make sure to include semi-colon to end the %INCLUDE command, but don't include a semi-colon in the contents of of the file.

data y;
   set x;
%include incl("if1file.sas","myfile.sas") ;
   then selektion=0;
   else selektion=1;
run;

A better solution might be to put the code into a macro variable (if less than 64K bytes).

%let condition=
and a = 0
and b = 0
;

data y;
   set x;
   if 1=1 &condition then selektion=0;
   else selektion=1;
run;

If it is longer than 64K bytes then define it as a macro instead.

%macro condition;
and a = 0
and b = 0
%mend;

data y;
   set x;
   if 1=1 %condition then selektion=0;
   else selektion=1;
run;

Upvotes: 1

Related Questions