Evaluate string fraction





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















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]









share|improve this question





























    0















    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]









    share|improve this question

























      0












      0








      0


      1






      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]









      share|improve this question














      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]






      sas






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 16 '18 at 19:29









      blacksiteblacksite

      5,77741748




      5,77741748
























          4 Answers
          4






          active

          oldest

          votes


















          2














          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;





          share|improve this answer



















          • 1





            Good use of input(scan , it is likely faster than jumping out to macro to resolve every frac value

            – Richard
            Nov 17 '18 at 11:49





















          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;


          enter image description here



          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





          share|improve this answer

































            2














            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.






            share|improve this answer

































              2














              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;





              share|improve this answer
























              • Good trick! coalesce defaults the denominator to 1 when frac does not have it's own. Consider using a format for presentation instead of converting back to string with put, i.e. fracval = scan(frac,1) / coalesce(scan(frac,2),1); format fracval 4.2;

                – Richard
                Nov 17 '18 at 11:54












              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53344230%2fevaluate-string-fraction%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              2














              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;





              share|improve this answer



















              • 1





                Good use of input(scan , it is likely faster than jumping out to macro to resolve every frac value

                – Richard
                Nov 17 '18 at 11:49


















              2














              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;





              share|improve this answer



















              • 1





                Good use of input(scan , it is likely faster than jumping out to macro to resolve every frac value

                – Richard
                Nov 17 '18 at 11:49
















              2












              2








              2







              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;





              share|improve this answer













              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;






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 16 '18 at 19:41









              Kiran Kiran

              2,97531020




              2,97531020








              • 1





                Good use of input(scan , it is likely faster than jumping out to macro to resolve every frac value

                – Richard
                Nov 17 '18 at 11:49
















              • 1





                Good use of input(scan , it is likely faster than jumping out to macro to resolve every frac value

                – Richard
                Nov 17 '18 at 11:49










              1




              1





              Good use of input(scan , it is likely faster than jumping out to macro to resolve every frac value

              – Richard
              Nov 17 '18 at 11:49







              Good use of input(scan , it is likely faster than jumping out to macro to resolve every frac value

              – Richard
              Nov 17 '18 at 11:49















              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;


              enter image description here



              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





              share|improve this answer






























                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;


                enter image description here



                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





                share|improve this answer




























                  2












                  2








                  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;


                  enter image description here



                  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





                  share|improve this answer















                  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;


                  enter image description here



                  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






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 16 '18 at 19:48

























                  answered Nov 16 '18 at 19:42









                  data _null_data _null_

                  5,572710




                  5,572710























                      2














                      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.






                      share|improve this answer






























                        2














                        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.






                        share|improve this answer




























                          2












                          2








                          2







                          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.






                          share|improve this answer















                          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.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 16 '18 at 19:58

























                          answered Nov 16 '18 at 19:51









                          Josh EllerJosh Eller

                          1,02727




                          1,02727























                              2














                              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;





                              share|improve this answer
























                              • Good trick! coalesce defaults the denominator to 1 when frac does not have it's own. Consider using a format for presentation instead of converting back to string with put, i.e. fracval = scan(frac,1) / coalesce(scan(frac,2),1); format fracval 4.2;

                                – Richard
                                Nov 17 '18 at 11:54
















                              2














                              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;





                              share|improve this answer
























                              • Good trick! coalesce defaults the denominator to 1 when frac does not have it's own. Consider using a format for presentation instead of converting back to string with put, i.e. fracval = scan(frac,1) / coalesce(scan(frac,2),1); format fracval 4.2;

                                – Richard
                                Nov 17 '18 at 11:54














                              2












                              2








                              2







                              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;





                              share|improve this answer













                              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;






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 16 '18 at 20:15









                              Shenglin ChenShenglin Chen

                              3,84769




                              3,84769













                              • Good trick! coalesce defaults the denominator to 1 when frac does not have it's own. Consider using a format for presentation instead of converting back to string with put, i.e. fracval = scan(frac,1) / coalesce(scan(frac,2),1); format fracval 4.2;

                                – Richard
                                Nov 17 '18 at 11:54



















                              • Good trick! coalesce defaults the denominator to 1 when frac does not have it's own. Consider using a format for presentation instead of converting back to string with put, i.e. fracval = scan(frac,1) / coalesce(scan(frac,2),1); format fracval 4.2;

                                – Richard
                                Nov 17 '18 at 11:54

















                              Good trick! coalesce defaults the denominator to 1 when frac does not have it's own. Consider using a format for presentation instead of converting back to string with put, i.e. fracval = scan(frac,1) / coalesce(scan(frac,2),1); format fracval 4.2;

                              – Richard
                              Nov 17 '18 at 11:54





                              Good trick! coalesce defaults the denominator to 1 when frac does not have it's own. Consider using a format for presentation instead of converting back to string with put, i.e. fracval = scan(frac,1) / coalesce(scan(frac,2),1); format fracval 4.2;

                              – Richard
                              Nov 17 '18 at 11:54


















                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53344230%2fevaluate-string-fraction%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Florida Star v. B. J. F.

                              Danny Elfman

                              Lugert, Oklahoma