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

2023-07-18  本文已影响0人  SASPRO的打工人生活

今天群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。

上一篇下一篇

猜你喜欢

热点阅读