Evaluate string fraction

2019-06-09 03:19发布

问题:

Suppose I have the following dataset:

data df;
input frac $;
datalines;
1/3
1/4
5/12
1
0
7/12
;
run;

And I want to get to this:

frac
0.33
0.25
0.42
1.00
0.00
0.58

I know I could get this output by doing this:

proc sql;
select
  case
    when frac = '1/12' then 0.083
    when frac = '1/6' then 0.167
    ...
  end as frac_as_num
from df
;
quit;

But I'd rather not hard-code everything. I know I could do something like this in Python:

frac = ['1/12', '1/6', ...]
[eval(f) for f in frac]

回答1:

something like below using scan and input should work.

 proc sql;
 create table want as 
 select frac, 
    case when index(frac,'/') then 
    input(scan(frac, 1),best32.)/input(scan(frac, 2),best32.) 
    else input(frac,best32.) end as frac_as_num format= 5.2
from df;


回答2:

This is how I would do it so that the results are numbers and have not been converted to and from character which would happen if you use %SYSEVALF via RESOLVE in a single step.

filename FT76F001 temp;
data _null_;
   file FT76F001;
   input frac $;
   put +3 'x=' frac ';' frac=$quote. '; output;';
   datalines;
1/3
1/4
5/12
1
0
7/12
;
run;

data frac;
   length x 8 frac $16;
   %inc FT76F001;
   run;
proc print;
   run;

This is using SYSEVALF

464  data _null_;
465     input frac $;
466     x = input(resolve(cats('%sysevalf(',frac,')')),f32.);
467     put 'NOTE: ' (_all_)(=);
468     datalines;

NOTE: frac=1/3 x=0.3333333333
NOTE: frac=1/4 x=0.25
NOTE: frac=5/12 x=0.4166666667
NOTE: frac=1 x=1
NOTE: frac=0 x=0
NOTE: frac=7/12 x=0.5833333333


回答3:

I'd say the simplest way to do it would be to put your fractional value into a macro variable, call the sysevalf function on it to evaluate the value, and finally convert it back into a normal variable. This has the added benefit of being able to work with any math expression, not just fractions.

Something like:

data test;
    set df;

    call symput('myMacroVariable',frac);            /* Put the value of frac into a macro variable */
    dec = resolve('%sysevalf(&myMacroVariable)');   /* Evaluate the value of the macro variable */
run;

Edit: Don't listen to me, data_null_'s answer does the same thing but in one line.



回答4:

data df;
input frac $;
_frac=put(scan(frac,1)/coalesce(scan(frac,2),1),4.2);
datalines;
1/3
1/4
5/12
1
0
7/12
;
run;


标签: sas