美文网首页
SAS编程:如何确定变量最大小数位数以及应用?

SAS编程:如何确定变量最大小数位数以及应用?

作者: 野藤_ | 来源:发表于2022-05-06 14:48 被阅读0次

    (PS:文章只写了一半,留作项目讨论用,讨论部分在2.1节)

    在临床项目试验中,会生成数值变量的描述性统计量的Table。各个统计量的小数位数的确定,不同的公司、不同的项目可能有不同的要求。

    有的,要求统计量展示固定的小数位数;有的,要求统计量小数位数根据原数据小数位数确定

    前者,直接固定统计量格式进行输出,无需特殊的处理;后者,需要获取原始数据的小数位数,进而判断输出统计量的保留位数后,进行输出。

    这篇文章介绍一下,后者的处理和应用过程。

    1. 小数位数确定

    原始数据小数位数的确定,一般有2个来源:

    第一,从保存在SPEC中的数值格式确定数据的小数位数;
    第二,直接从数据集中获取数据的最大小数位数。

    1.1 SPEC中的格式

    SPEC中,会规定输出变量的格式,数值变量的小数位数可以从格式中获取。

    SPEC信息一般保存在EXCEL中,导入SAS数据集不复杂,有的公司直接把SPEC的信息保存在特定的逻辑库中。

    我以P21的SPEC为例,项目中SPEC的内容与这个类似:

    P21

    从SPEC中,可以获取到参数的名称、参数结果的数据类型、有效小数位数。程序中,稍加整理,不复杂就可以获得以下内容的数据集。

    **Import SPEC:
    options validvarname = v7;
    
    proc import datafile="XXX_p21e_adam.xlsx" out = vlm1
        dbms =  xlsx replace;
        getnames = yes;
        sheet = "ValueLevel";
    run;
    
    **Get decimal information;
    data vlm;
      set vlm1;
      where dataset = "ADLB" and data_type = "float";
      
      length paramcd $8;
    
      paramcd = scan(where_clause, 4, ".");
      decimal = significant_digits;
    
      keep dataset paramcd decimal;
    run;
    
    ADLB Decimal
    1.2 从原始数据集获取小数位数

    我用一个ADLB数据集进行演示:

    ADLB

    整个思路是,将每个Paramcd的数值检测值以best.格式Put出来,以小数点.右侧字符的长度作为该值的小数位数,取变量值中最大的小数位数值

    这里有一个注意点,整数Put出来的字符是没有小数点.的,所以需要单独判断。

    libname test "E:\99_Test";
    
    proc sql noprint;
      create table decimal as
        select distinct paramcd, 
            max(case
                when index(strip(put(aval,best.)), ".")= 0 then 0
                else length(scan(strip(put(aval,best.)), 2, "."))
              end) as decimal
          from test.adlb
          where aval ne .
          group by paramcd;
    quit;
    
    ADLB Decimal

    2.小数位数确定之后,如何应用?

    描述性统计量的小数位数,一般的要求是:n保留整数;Max、Min与原数据小数位数一致;Mean、Median比源数据多保留1位小数;SD比源数据多保留2位小数。同时,统计量展示的最大小数位数一般不超过4位。

    具体如何展示,还需要看项目中的要求,并不固定。这篇文章,以上面的要求来进行举例。

    2.1 小数位数的基础应用

    最基础的小数位数应用,是使用SAS的put语句,常用的方法是直接Put具体的数字格式。不过,这中处理方式在负数十分位向0进位时,可能会产生一些偏误

    我用代码进行实例,对数字0.4, 0.5, -0.4, -0.49 -0.5四舍五入保留整数。使用两种方法,一种是直接put数值格式8.0;一种是使用函数Round处理之后,再put数值格式8.0

    data tmp;
        input a @@;
    
        bput = strip(put(a, 8.0));
        bround = strip(put(round(a, 1), 8.0));
        
        datalines;
            0.4
            0.5
            -0.4
            -0.49
            -0.5
        ;
    run;
    
    Result 1

    从结果中可以看到,对于-0.4-0.49这2个数值,四舍五入应该进位成0,但是直接Put时,结果是-0,与想要的结果不同。更一般的,对于(-0.5, 0)这个范围的数,Put保留整数时,结果为-0

    我没细究这个现象的原因,建议大家在保留小数位数时,先使用Round函数,再put相应的格式。两个函数保留的小数位数要相同,否则会产生二次误差

    2.2 单个Paramter的统计量的小数位数处理

    数值变量统计量的小数位数处理,受到如何处理所有参数的影响。

    以ADLB举例,分析数据集有多个数值型结果的参数。这里有两种处理方式,第一,一次对一个参数进行统计输出,其他参数依次重复;第二,将Paramter作为分组变量,一次处理所有需要分析的参数结果

    对应的,小数位数保留的处理也因此不同。

    先先计算出数值变量的统计量:

    **Create formats for output;
    
    **Get statitstics;
    proc means data = test.adlb noprint nway;
        by trt01an ;
        where paramcd = "APTT" and aval ne .;
    
        var aval;
    
        output out = stats1 n = n_ mean = mean_ std = sd_ median = median_ min = min_ max=max_;
    run;
    
    stat1

    从从面可以知道,参数的APTT的小数位数为1,按照规则,小数位数处理如下:

    data stats2;
        length n mean sd median min max  $50;
        set stats1;
    
        n =strip(put(n_, best.));
        mean =strip(put(round(mean_, 0.1**(1+1) ), 8.2));
        sd =strip(put(round(sd_, 0.1**(1+2) ), 8.3));
        median =strip(put(round(median_, 0.1**(1+1) ), 8.2));
        min =strip(put(round(min_, 0.1**(1+0) ), 8.1));
        max =strip(put(round(max_, 0.1**(1+0) ), 8.1));
    
    run;
    
    stats2

    工作中,我们不能直接用1来代入,这样就是Hard Coding了。我们可以将APTT的小数位数保留到宏变量中,直接在宏中进行引用。

    整个过程处理如下:

     
    

    相关文章

      网友评论

          本文标题:SAS编程:如何确定变量最大小数位数以及应用?

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