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

Hi,

I have a dataset Ywith one column, CONDITION which is a string.

When I try to do this:

data X;

  set Y;

  length Logs $400.;

  call symput('cond',CONDITION);

  Logs = "&cond";

run;

I expect that LOGS contains exactly the same value as CONDITION for every row, but instead it contains some random CONDITIONS from other rows. It doesn't seem to be updated every row.

What am I doing wrong?

(That code is just a snippet of a more complex process).

Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
jakarman
Barite | Level 11

When you using 9.4 you could try using SAS(R) 9.4 Functions and CALL Routines: Reference, Second Edition (dosubl)
Due to the PDV approach in a datastep I doubt the SAS interpreter is suited for dynamic code execution as some interpreters languages are having.

the call execute and writing a source reading it in are different technical methods but achieving the same.
Design you next datastep to be executes from a first one very cumbersome for the code processor 

Another is using SAS(R) 9.4 Functions and CALL Routines: Reference, Second Edition (vvalue) resolving all variable values and the resolve funtions with an evaluate macro expression

SAS(R) 9.4 Functions and CALL Routines: Reference, Second Edition (resolve)

Seen this question before, is it a study problem or real life issue.

---->-- ja karman --<-----

View solution in original post

12 REPLIES 12
Reeza
Super User

Generally, you can't use a macro variable in the same datastep that you created in. If you explain more about what you're trying to do, then we can provide more info.

Based on your current code, I would expect the macro variable to be equivalent to the last line of data.

jakarman
Barite | Level 11

If you review the macro language manual you will see macro processing is text processing before all other language processing is done.

A macro value reference using the & reference must be done before your data step as it will become static text.

The use of symget and symput is more dynamic but having cautions eg local/global.

All as documented nothing weird.

---->-- ja karman --<-----
Haikuo
Onyx | Level 15

Just like being pointed out by Jaap and Reeza, it is documented behavior. When you use notation "&cont", you are supposed to have it ready during the COMPILE TIME. Even though I don't know the purpose of your code, but to get what you expected, you need to use the RUN TIME functions, such as:

data X;

  set Y;

  length Logs $400.;

   call symput('cond',CONDITION);

  /*Logs = "&cond";*/

logs=symget('cond');

run;

Haikuo

Edoedoedo
Pyrite | Level 9

You all have right, that was really a stupid mistake...

However this is what I need to do: I have a dataset with some variables C1,C2,C3,... and a character variable CONDITION. CONDITION is a string which contains a logic expression based on C1,C2,C3,...; I need to evaluate CONDITION for each row, and create a new variable which is either 1 or 0 depending of the result of CONDITION.

Example:

C1      C2      C3      CONDITION

0          2          1          C1+C3 = C2

1          1          3          C1*C2+C3 = 4

The result dataset should be:

C1      C2      C3      CONDITION               RESULT

0          2          1          C1+C3 = C2                    0

1          1          3          C1*C2+C3 = 4                 1

I don't know how to perform the evaluation of CONDITION and apply it to each row. What do you recommend?

Thanks a lot.

Regards

Haikuo
Onyx | Level 15

what version of SAS you have?

Edoedoedo
Pyrite | Level 9

It is: SAS 9.3 TS1M2

Tom
Super User Tom
Super User

Might be easiest to generate a lot of code.

You could try to do it with macro variables but then your CONDITION would need the & to reference the macro variables.

data have ;

input c1-c3 condition $20.;

cards;

0 2 1 C1+C3=C2

1 1 3 C1*C2+C3=4

;;;;

data want ;

  set have ;

  array c c1-c3 ;

  do i=1 to dim(c);

    call symputx(vname(c(i)),c(i));

  end;

  condition2 = tranwrd(upcase(condition),'C','&C') ;

  cresult = resolve('%eval('||trim(condition2)||')') ;

  result = input(cresult,1.);

  put (_all_) (=);

run;

jakarman
Barite | Level 11

When you using 9.4 you could try using SAS(R) 9.4 Functions and CALL Routines: Reference, Second Edition (dosubl)
Due to the PDV approach in a datastep I doubt the SAS interpreter is suited for dynamic code execution as some interpreters languages are having.

the call execute and writing a source reading it in are different technical methods but achieving the same.
Design you next datastep to be executes from a first one very cumbersome for the code processor 

Another is using SAS(R) 9.4 Functions and CALL Routines: Reference, Second Edition (vvalue) resolving all variable values and the resolve funtions with an evaluate macro expression

SAS(R) 9.4 Functions and CALL Routines: Reference, Second Edition (resolve)

Seen this question before, is it a study problem or real life issue.

---->-- ja karman --<-----
Edoedoedo
Pyrite | Level 9

It is a real life problem, I have a set of rule written in Excel which is maintained by some office, and I must apply these rules to my dataset. I could write every if, but the rules can change anytime and the dataset must reapply them dynamically.

Anyhow I read your links and I figured out how to do it!

Thanks a lot.

Ksharp
Super User

You can't use it in the same datastep , but there is one exception.

call symput('cond',CONDITION);

  Logs = symget(&cond);

DonStanley
Calcite | Level 5

This came up as an example in another forum of where symput/symget has to be used to solve a real world problem. However it is not necessary and just serves to complicate the coding. As the problem has been stated, this code works fine.

filename codefile '/folders/myshortcuts/SASUniversityEdition/test.txt' ;

data test ;

infile cards ;

length c1 c2 c3 8 condition $ 20 ;

input c1 c2 c3 condition $30. ;

file codefile;

put 'if ' condition ' then result = 1 ; else result = 0 ;' ;

cards ;

0          2          1          C1+C3 = C2

1          1          3          C1*C2+C3 = 4

;;run ;

data test2 ;

  set test ;

  %include codefile ;

  run ;

 

filename codefile clear ; 

proc print data=test2 ; run ;

1

021C1+C3 = C20
2113C1*C2+C3 = 4

1

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 12 replies
  • 1513 views
  • 8 likes
  • 7 in conversation