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

Hi - please bear with me here.

 

I have a 3rd party data source that provides us data based on specific conditions an order has hit. We do not know which conditions were hit so cannot analyse any data. Within the data, we do get a score set and i have managed to give each condition its own score based on bits:

 

RuleWeight
1-32768
2-16384
3-8192
4-4096
5-2048
6-1024
7-512
8-256
9-128
10-64
11-32
12-16
13-8
14-4
15-2
16-1

 

The idea is, that if the score is -580, there are only 3 rules it could possibly be (7,10,14), or -65535 it would have hit all 16 - so we can then know which rules were hit.

 

My question is: Is there a way of coding into sas a way to work out which rules were hit? Working it out manually for each score would take an age.

 

I hope i have explained myself? Any help is much appreciated.

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

See my take:

data rules;
infile datalines dlm='09'x dsd;
input rulenumber rulevalue;
datalines;
1	-32768
2	-16384
3	-8192
4	-4096
5	-2048
6	-1024
7	-512
8	-256
9	-128
10	-64
11	-32
12	-16
13	-8
14	-4
15	-2
16	-1
;
run;

data have;
input value;
datalines;
-580
;
run;

data want;
if _n_ = 1
then do;
  array rules {16} _temporary_;
  do i = 1 to 16;
    set rules;
    rules{i} = rulevalue;
  end;
end;
set have;
_val = value;
length rules_hit $100;
do i = 1 to dim(rules);
  put _val=;
  put rules{i}=;
  if _val <= rules{i}
  then do;
    rules_hit = catx(',',rules_hit,put(i,2.));
    _val = _val - rules{i};
  end;
end;
keep value rules_hit;
run;
    
proc print data=want noobs;
run;

Result:

value    rules_hit

 -580    7,10,14 

View solution in original post

6 REPLIES 6
MattehWoo
Calcite | Level 5
Correct - i was looking at the wrong numbers!
Kurt_Bremser
Super User

See my take:

data rules;
infile datalines dlm='09'x dsd;
input rulenumber rulevalue;
datalines;
1	-32768
2	-16384
3	-8192
4	-4096
5	-2048
6	-1024
7	-512
8	-256
9	-128
10	-64
11	-32
12	-16
13	-8
14	-4
15	-2
16	-1
;
run;

data have;
input value;
datalines;
-580
;
run;

data want;
if _n_ = 1
then do;
  array rules {16} _temporary_;
  do i = 1 to 16;
    set rules;
    rules{i} = rulevalue;
  end;
end;
set have;
_val = value;
length rules_hit $100;
do i = 1 to dim(rules);
  put _val=;
  put rules{i}=;
  if _val <= rules{i}
  then do;
    rules_hit = catx(',',rules_hit,put(i,2.));
    _val = _val - rules{i};
  end;
end;
keep value rules_hit;
run;
    
proc print data=want noobs;
run;

Result:

value    rules_hit

 -580    7,10,14 
Astounding
PROC Star

As @Kurt_Bremser has demonstrated, it's easy enough for a computer to calculate all the possibilities.  While I disagree with his choice of variable names (ruleshit), here is what might be a simpler way:

 

data combos;

array rule {16};

do rule1=0, -32768;

do rule2=0, -16384;

do rule3=0, -8192;

do rule4=0, -4096;

do rule5=0, -2048;

do rule6=0, -1024;

do rule7=0, -512;

do rule8=0, -256;

do rule9=0, -128;

do rule10=0, -64;

do rule11=0, -32;

do rule12=0, -16;

do rule13=0, -8;

do rule14=0, -4;

do rule15=0, -2;

do rule16=0, -1;

total = sum(of rule1-rule16);

length rules_hit $ 40;

rules_hit = ' ';

do k=1 to 16;

   if rule{k} ne 0 then rules_hit = catx(',' , rules_hit, k);

end;

output;

end; end; end; end; end;

end; end; end; end; end;

end; end; end; end; end;

end;

keep total rules_hit;

run;

 

This allows you to sort and merge with your scores (or perhaps some other form of look-up).

 

data_null__
Jade | Level 19

You can easily extract the rule numbers by examining the bit string of the positive value of value.  Here I do it as a 16 byte character variable.

 

data have;
   input value;
   bitvalue = put(-value,binary16.);
   f=findc(bitvalue,'1',1);
   length ruleshit $64;
   do while(f);
      ruleshit = catx(', ',ruleshit,f);
      f = f + 1;
      f=findc(bitvalue,'1',f);
      end;
   drop f;
   datalines;
-580
-321
-0
-512
-65535
;;;;
   run;

Capture.PNG

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!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 6 replies
  • 901 views
  • 1 like
  • 4 in conversation