美文网首页
252:如何将分数转换成数值型小数

252:如何将分数转换成数值型小数

作者: SASPRO的打工人生活 | 来源:发表于2023-07-18 15:25 被阅读0次

    今天群group里有一个人问:如何将1/4转换成数值型的0.25?
    有一位小可爱直接通过分隔符"/"拆分出分子分母然后相除,我想说的是这样不一定是错误的,只是关注到她好几次这样简单粗暴的解决问题,显得有些可爱。虽然有时候能解决问题,但是考虑的不全面。

    至于读者为什么会有这样的一个问题,我不清楚,在工作中好像也没有遇到,便去搜了一下,SAS官网上好像没有直接的函数能够解决这样的问题,但是也不是说就不能解决了。

    方法一:

    就像小可爱说的直接拆分相除,但是的话,如果原始数据不是分数形式,比如说现在有两个字符型值,一个是"1/4",一个是“0.75”,如果只是单纯的相除的话,那么对于0.75,在计算的时候,会报这样一个Note:

    data test;
      c="0.75";
      newvar = input(scan(c, 1, "/"), best.) / input(scan(c, 2, "/"),??best.);
    run;
    
    image.png

    所以为了避免这种情况,你要么提前加一个if index(c,"/"),要么采用下面这种写法:

    data test;
      c="0.75";
      newvar = input(scan(c, 1, "/"), best.) / coalesce(input(scan(c, 2, "/"), ?? best.), 1);
      d="1/4";
      newvar2 = input(scan(d, 1, "/"), best.) / coalesce(input(scan(d, 2, "/"), ?? best.), 1);
    run;
    
    image.png

    但是不知道会不会有“1/0”的情况,如果有的话,还是需要判断分母不为0.

    这里顺便介绍一下COALESCE函数,作用就是返回一系列数值型列表里面的第一个非空或者非缺失值。这好像有的面试也会问到。

    data test;
      CC=coalesce(0,1);
      DD=coalesce(.,2,1);
      EE=coalesce(.B,8,1);
      FF=coalesce(.,.,.);
    run;
    
    image.png

    注意EE=coalesce(.B,8,1);这里的.B也是数值型,也是非空的,但是还是选到了8,说明了要数字形式的才会输出。

    对应的搜索字符型表达式的函数就是COALESCEC。
    方法二:

    data test;
      c="0.75";
      newvar = input(resolve( '%sysevalf(' || c || ')' ),best.);
      d="1/4";
      newvar2 = input(resolve( '%sysevalf(' || d || ')' ),best.);
    run;
    
    image.png

    首先介绍resolve函数:
    Returns the resolved value of the argument after the argument has been processed by the macro facility.

    resolve的一个作用就是返回一个字符文本,而这个字符文本是来自macro facility解析之后的一个值。语法格式就是:
    variable = RESOLVE(argument);

    RESOLVE能处理的三种类型的参数如下
    ● DATA step variable names
    ● Text enclosed in single quotes
    ● Character expressions

    用单引号括起来的一个文本,看一个例子:

    %let test=5;
    
    data b;
      w = &test;
      y = resolve('&test');
    run;
    
    image.png

    那么在本文中的例子,应该是属于第三种类型

    所以上面的resolve( '%sysevalf(' || d || ')' ),简化一下就是
    ' %sysevalf(' 这是一起的,用单引号括起来防止被宏扫描器发现,
    然后拼接符拼上d变量的值,注意不会把D的双引号也拼过来啊!就跟我们平时用拼接符拼接变量是一样的,除非双引号里面还有引号才会拼上引号。
    最后再拼上')'

    所以最后运行的是resolve(%sysevalf(1/4));
    而%sysevalf的作用就是使用浮点运算计算算术和逻辑表达式。

    比如下面这样

    %let x = %sysevalf(7/3);
    %put Using SYSEVALF &=x;
    
    image.png

    最后resovle返回的就是%sysevalf计算后的值,也就是0.25,但是是字符型的,我们只要input一下就可以了。

    同时,在查阅资料的过程中,发现在SAS中有一个直接将数值型转换成分数的功能,就是FRACTw. Format。

    这个W是指定输出的宽度。

    data test;
      do a=0.666,1.25,0.75,0.66666666666;
        b=put(a,fract10.);
        output;
      end;
    run;
    
    image.png

    但是好像不会转换成假分数,而且如果是0.5的话,只会转换成1/2,但是50/100也是0.5。

    相关文章

      网友评论

          本文标题:252:如何将分数转换成数值型小数

          本文链接:https://www.haomeiwen.com/subject/jjmnudtx.html