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

Hello All

I'm trying to replicate in SAS a procedure I use in Excel. This procedure is basically an iterative solver (through a macro) that puts the variable Delta (OptVar - Ratio) to 0 by changing the values of the AuxVar (starting with null values).

 

The input data starts like this:

 

 ID  Num    Ratio     AuxVar   OptVar  Delta

160.1666670.00%0.00%-0.1667
270.2857140.00%0.00%-0.2857
370.2857140.00%0.00%-0.2857
48000.3750.00%0.00%-0.3750
58000.3750.00%0.00%-0.3750
67440.3870970.00%0.00%-0.3871
67440.3870970.00%0.00%-0.3871
720.50.00%0.00%-0.5000
820.50.00%0.00%-0.5000

 

- ID, Num and Ratio are inputs;

- AuxVar values are generated by Excel;

- OptVar is given by probit(0.975)*sqrt((AuxVar*(1-AuxVar))/Num)+AuxVar

- Delta is OptVar - Ratio

 

The solver objective function is Delta, it operates by changing AuxVar values and the constraint is AuxVar greater or equal to 0. It runs for each cell.

 

After the Solver Macro, the output is:

 

 ID  Num    Ratio       AuxVar   OptVar   Delta

160.1666673.01%16.67%0.0000
270.2857148.22%28.57%0.0000
370.2857148.22%28.57%0.0000
48000.37534.21%37.50%0.0000
58000.37534.21%37.50%0.0000
67440.38709735.28%38.71%0.0000
67440.38709735.28%38.71%0.0000
720.59.45%50.00%0.0000
820.59.45%50.00%0.0000

 

Is there a way to do this in SAS? 

 

I have been trying and searching for a few days, without success.

 

If anyone could help, it would be very appreciated.

 

Kind Regards,

 

Ricardo

1 ACCEPTED SOLUTION

Accepted Solutions
PGStats
Opal | Level 21

Proc FCMP provides a solver that can do this:

 

proc fcmp outlib=work.fcmp.stuff;
function OptVar(AuxVar, Num);
return ( probit(0.975)*sqrt((AuxVar*(1-AuxVar))/Num) + AuxVar );
endsub;
function AuxVar(Num, ratio);
return ( solve("OptVar", {0.1}, ratio, ., Num) );
endsub; 
run;

options cmplib=(work.fcmp);

data have;
input  ID  Num    Ratio;
auxVar = AuxVar(Num, Ratio);
format optVar auxVar percent8.2;
optVar = OptVar(auxVar, Num);
datalines;
1	6	0.166667
2	7	0.285714
3	7	0.285714
4	800	0.375
5	800	0.375
6	744	0.387097
7	2	0.5
;

proc print data=have; run;
                Obs    ID    Num     Ratio       auxVar      optVar

                 1      1      6    0.16667      3.01%      16.67%
                 2      2      7    0.28571      8.22%      28.57%
                 3      3      7    0.28571      8.22%      28.57%
                 4      4    800    0.37500     34.21%      37.50%
                 5      5    800    0.37500     34.21%      37.50%
                 6      6    744    0.38710     35.28%      38.71%
                 7      7      2    0.50000      9.45%      50.00%

Nore: If this is a power calculation, you might want to look at the Power proc.

PG

View solution in original post

3 REPLIES 3
PGStats
Opal | Level 21

Proc FCMP provides a solver that can do this:

 

proc fcmp outlib=work.fcmp.stuff;
function OptVar(AuxVar, Num);
return ( probit(0.975)*sqrt((AuxVar*(1-AuxVar))/Num) + AuxVar );
endsub;
function AuxVar(Num, ratio);
return ( solve("OptVar", {0.1}, ratio, ., Num) );
endsub; 
run;

options cmplib=(work.fcmp);

data have;
input  ID  Num    Ratio;
auxVar = AuxVar(Num, Ratio);
format optVar auxVar percent8.2;
optVar = OptVar(auxVar, Num);
datalines;
1	6	0.166667
2	7	0.285714
3	7	0.285714
4	800	0.375
5	800	0.375
6	744	0.387097
7	2	0.5
;

proc print data=have; run;
                Obs    ID    Num     Ratio       auxVar      optVar

                 1      1      6    0.16667      3.01%      16.67%
                 2      2      7    0.28571      8.22%      28.57%
                 3      3      7    0.28571      8.22%      28.57%
                 4      4    800    0.37500     34.21%      37.50%
                 5      5    800    0.37500     34.21%      37.50%
                 6      6    744    0.38710     35.28%      38.71%
                 7      7      2    0.50000      9.45%      50.00%

Nore: If this is a power calculation, you might want to look at the Power proc.

PG
Baelin10
Calcite | Level 5

Thank you very very much, you solved a big issue here. Worked like a charm! 

 

Best regards,

 

Ricardo Soares

ChrisNZ
Tourmaline | Level 20

You can always try the brute-force approach.

 

data HAVE;
  retain RATIO 0.166667 NUM 6 ;
run;
data WANT;    
  DELTA=9999;
  set HAVE;
  do I = 0 to 1 by 1e-6;
    VAL = probit(0.975)*sqrt((I*(1-I))/NUM)+I;
    if . < abs(VAL - RATIO) < DELTA then do;   
      DELTA  = abs(VAL - RATIO) ;
      OPTVAR = VAL;
      AUXVAR = I;
    end; 
  end;
  putlog OPTVAR= percent9.2 AUXVAR= percent9.2;
run;

OPTVAR=16.67% AUXVAR=3.01%

 

[Edit : I didn't see the previous reply. @PGStats 's solution is smarter. ]

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 3 replies
  • 3397 views
  • 1 like
  • 3 in conversation