BookmarkSubscribeRSS Feed
arpitsharma27
Calcite | Level 5

Hello,

 

I have this:

data have;
input value lower :$10. upper :$10.;
infile datalines dlm=",";
datalines;
0.0035,>=0.0035,<=0.034
0.034,>=0.0035,<=0.034
0.0045,>=0.0035,<=0.034
;run;

Within a Datastep(not _NULL_), I want to evaluate the condition

value||lower/*value >=0.0035*/

and

value||upper/*value <=0.034*/

and if the conditions are met then create another variable- flag with value "GOOD" else value should be "BAD".

 

Please advise.

12 REPLIES 12
ballardw
Super User

@arpitsharma27 wrote:

Hello,

 

I have this:

data have;
input value lower :$10. upper :$10.;
infile datalines dlm=",";
datalines;
0.0035,>=0.0035,<=0.034
0.034,>=0.0035,<=0.034
0.0045,>=0.0035,<=0.034
;run;

Within a Datastep(not _NULL_), I want to evaluate the condition

value||lower/*value >=0.0035*/

and

value||upper/*value <=0.034*/

and if the conditions are met then create another variable- flag with value "GOOD" else value should be "BAD".

 

Please advise.


To make this a proper exercise you need to show 1) multiple comparisons that vary between records not just two applied to all records as that is easily done in the code or a format and not worth bothering with read in values; and 2) show what you expect the result to look like.

arpitsharma27
Calcite | Level 5

If this helps:

If the value of the variable-VALUE is within the values of LOWER and UPPER then another variable named FLAG needs to be created with value of "GOOD" else it should have a value of "BAD".

mkeintz
PROC Star

You already apparently know:

  1. The values of lower and upper, in eponymously named variables.
  2. And you want always to compare  <= or >=   (i.e. not strictly < or >).

If so, then why are you reading in lower and upper as text?  Why not read the numbers and do direct numeric comparisons?

 

I suspect there must be more to your task than what you have shown.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
arpitsharma27
Calcite | Level 5

Obviously I put a template here. Once I get the idea of how code works, I can use it.

Anyways, I think I figured out  using dosubl

 

data want;
set have;
condition=cats(value,lower);
_n_=dosubl('data _null_ ; call symputx("check", '||condition||'); run;');
check=symget('check');
run;
ChrisNZ
Tourmaline | Level 20

No macro and no sub-sessions and one clean results table if you do this:

data WANT;
  set HAVE;
  if _N_=1 then call execute('data WANT; length LOWER UPPER $10;');
  call execute(catt('VALUE=', VALUE, ';LOWER="', LOWER, ' ";UPPER="', UPPER, ' "; '); 
  call execute(catx(' ', 'if', VALUE, LOWER, 'then FLAG_LOWER="GOOD";');
  call execute(catx(' ', 'if', VALUE, UPPER, 'then FLAG_UPPER="GOOD";');
  call execute('output;');
run;
run;

 

mkeintz
PROC Star

@ChrisNZ 

 

I like your solution, but really it is effectively using a "data _null_" approach.  Your code just makes it into a "data want", immediately overwritten by a second "data want".   I think the dosubl solution is likely the only way to avoid an "outer" data _NULL_, which I suspect is the criterion meant by the OP.  

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
ChrisNZ
Tourmaline | Level 20

@mkeintz The data _null_ restriction is weird, and I see data _null_ in the call dosubl logic too.

Not too sure what the end goal is, but if it is just an intellectual exercise to avoid data _null_ then the call dosubl solution fails too.

One way would be to do it would be by using a macro and functions open() and getvarn() and resolve the test there. Other than that, a data step is needed.

 

mkeintz
PROC Star

@ChrisNZ wrote:

@mkeintz The data _null_ restriction is weird, and I see data _null_ in the call dosubl logic too.

Not too sure what the end goal is, but if it is just an intellectual exercise to avoid data _null_ then the call dosubl solution fails too.

One way would be to do it would be by using a macro and functions open() and getvarn() and resolve the test there. Other than that, a data step is needed.

 


Understood.  I took the restriction to mean that there would be no use of DATA _NULL_ in the outer loop/domain, thereby providing the call dosubl approach a loophole.

 

But I think @Ksharp 's use of the resolve function best suits my understanding of the OP's conditions, and neatly complements the title of this thread ("Resolve Conditions in a datastep").

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
ChrisNZ
Tourmaline | Level 20
Agreed, @Ksharp 's reply is probably the best reply so far to match the specs.
ballardw
Super User

@arpitsharma27 wrote:

Obviously I put a template here. Once I get the idea of how code works, I can use it.

Anyways, I think I figured out  using dosubl

A big caution with simple templates. If they are too simple then you are implying the actual process is less complicated than it actually is. For example, if your real problem involves multiple different comparisons then you should provide examples of those as well.

Reasons: Your initial post would be much better of just placing the EXACT SAME comparisons into to code. No need to dirty up code for a the same comparison will all values.

The approaches provided that involve 2 comparisons may not work as expected if there is only one comparison. This is quite likely in the case of only having an Upper comparison that involves < in any form and a missing value. since MISSING is lest than anything. Note: you did not state that the value is never missing. Considerations for that may need to be applied.

And what happens if you throw in a third comparison? Or another value?

Providing essentially one use case for the comparison boundaries is quite likely to lead to code that is not quite what is needed.

Ksharp
Super User
data have;
input value lower :$10. upper :$10.;
infile datalines dlm=",";
datalines;
0.0035,>=0.0035,<=0.034
0.034,>=0.0035,<=0.034
0.0045,>=0.0035,<=0.034
0.45,>=0.0035,<=0.034
;run;

data want;
 set have;
 flag=resolve(cat('%sysevalf(',cats(value,lower),' and ',cats(value,upper),',boolean)'));
run;
Kurt_Bremser
Super User

Which comparison operators are to be expected in the lower and upper variables?

Will lower always contain the low end (and upper the top), or could this be reversed?

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 12 replies
  • 1634 views
  • 6 likes
  • 6 in conversation