DATA Step, Macro, Functions and more

SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

Reply
Contributor
Posts: 72

SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

Hi.

 

I have a dataset in which one of the variable has arithmetic expression. These expression are entered by user and it contains syntax errors. See dataset below where observation 2,3 and 4 are incorrect expression. If I use sysevalf or evalf function to evaluate them it throws the syntax error as below.

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required.

 

data have;
input exp $20.;
cards;
701*10 ** 6
4..60*10 ** 6
6t.22 * 10**-4
2*10**-3s
;
run;

 

 

IS there any function to parse these expression befor applying the sysevalf function. Please help.

 

Thanks,

Anand

Super User
Posts: 17,928

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

Depends. It looks like the errors are in the variables with characters? If so you could use anyalpha to identify records that may be an issue. However, with a user entered field you're bound to find errors in unknown and unpredictable ways. It may be better to try and catch the error rather than accommodate for it. Not sure how that's accomplished in SAS.
Super User
Posts: 9,691

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

There are a lot of pattern you need to match. This one could relieve your task.

 

data have;
input exp $20.;
if prxmatch('/^((-?\d+(\.\d+)?)(\+|-|\*{1,2}|\/)?)+$/',compress(exp)) then
x=resolve(cats('%sysevalf(',exp,')')); 
cards;
701*10 ** 6
4..60*10 ** 6
6t.22 * 10**-4
2*10**-3s
;
run;
Contributor
Posts: 72

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

Thank you Both.

Regular expression solution is working partially. But its not working for all the formulas. I am not well versed in regular expression so trying to fine tune it. 

 

for e.g. if the rule is like this (45.25/46.00*23.06). This contains the open and close braces. Its not evaluating such rules.

 

 

Super User
Posts: 9,691

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

My Perl Regular Expression would cover (45.25/46.00*23.06) .
As I said before, there are too many rules you need consider. You can't expect what kind of error the user would enter . The only way is to enhance and perfect the PRX better and better .
Super User
Posts: 5,096

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

Depending on what you consider a solution to be, consider this approach:

 

data _null_;

call execute('data _null_; set have; file print;');

do until (done);

   set have end=done;

   call execute ('testvar = ' || exp || '; put exp @ ;');

   call execute ('if testvar=. then put @25 "Result:  Not valid"; else put @25 "Result:  Valid";')

end;

call execute('run;');

run;

 

The intent is to generate a report showing whether each expression is valid or not.  I'm just not sure if that is an acceptable outcome or not.  Also note, the code is untested so it may need slight tweaking.

 

Good luck.

Contributor
Posts: 72

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

 

This solution is failing as we are really not checking the rule prior to the execution. Directly executing the rule is throwing the syntax error.

 

 

 

Super User
Posts: 17,928

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

You can't fix bad design/process with coding on the back end. You may want to find a way to clean the formula's before you bring them into SAS or some other way. As phrased this seems a bit like a programming exercise.
Super User
Posts: 5,096

Re: SYSEVAF function to evaulate a expression stored in character (SKIP syntax)

OK, one last try at what I think you need to solve here.  It is only being applied to one formula at a time, since it appears that you need to decide whether or not to proceed with processing based on whether the formula is valid.

 

data _null_;

input exp $20.;

call symputx('formula', exp);
cards;
701*10 ** 6

;

%let proceed=Y;

data _null_;

check = &formula;

if check=. then call symputx('proceed', 'N');

run;

%if &syserr > 0 %then %let proceed=N;

 

This gives you a macro variable &PROCEED that will be Y if you are safe, but N if either bad outcome is present:  the input formula contains invalid syntax, or the input formula generates a missing value (possibly because of referring to an unknown variable name).

 

Are we getting close?

Ask a Question
Discussion stats
  • 8 replies
  • 309 views
  • 1 like
  • 4 in conversation