欢迎光临散文网 会员登陆 & 注册

SAS Training 002 - 聊一聊贴标签 labeling

2021-08-12 00:55 作者:陆震同学  | 我要投稿

前几天给药品💊编盲,贴了大量的标签🏷️。今天我们就来聊聊贴标签,不同的是,我们聊聊 SAS 里的贴标签(labeling)。

直接进入主题。我们这里所说的 labeling,其实是进行格式的 label。SAS 中已经有对数字、日期等可用的格式,但是我们 programming 不满足于此,想更大可能地简化我们的工作,这时候,自定义 labeling 就呼之欲出了。

最直接的例子,现有一个分类变量,取值 1、2、3,你想依据其进行分组编码(high、mid、low),但是在分析过程中,你只想以 1、2、3 简单代替实际分组 character,怎么办?对分类变量的各 value 进行 labeling。

实际上,labeling 主要有两种:对 variable 进行 format,以及对 varaible 的取值 value 进行 format。我们一一来看。

creating variable labels

首先,准备演示数据集:

DATA auto;    INPUT make $ mpg rep78 weight foreign;    CARDS;        AMC     22 3 2930 0        AMC     17 3 3350 0        AMC     22 . 2640 0        Audi    17 5 2830 1        Audi    23 3 2070 1        BMW     25 4 2650 1        Buick   20 3 3250 0        Buick   15 4 4080 0        Buick   18 3 3670 0        Buick   26 . 2230 0        Buick   20 3 3280 0        Buick   16 3 3880 0        Buick   19 3 3400 0        Cad.    14 3 4330 0        Cad.    14 2 3900 0        Cad.    21 3 4290 0        Chev.   29 3 2110 0        Chev.   16 4 3690 0        Chev.   22 3 3180 0        Chev.   22 2 3220 0        Chev.   24 2 2750 0        Chev.   19 3 3430 0        Datsun  23 4 2370 1        Datsun  35 5 2020 1        Datsun  24 4 2280 1        Datsun  21 4 2750 1    ; RUN; PROC CONTENTS DATA= auto; RUN;

我们来使用 label statement 对其中的遍历 foreign、mpg 和 rep78 进行 labeling,看看结果啥样:

DATA auto2;    SET auto;    LABEL rep78= "1978 Repair Record"          mpg= "Miles Per Gallon"          foreign= "Where Car Was Made"; RUN; PROC CONTENTS DATA= auto2; RUN;

哎,有变化。多出一列 label。我们可以把它当作对 variable name 的一种详细描述。这里,需要注意的是:一旦我们在 data 步完成 labeling,其 label 在这个数据集后续的所有操作中是永久有效的;而作为对比,如果是在 proc 步中 labeling,那么该 label 只是在该 proc 步有效。我们来瞧瞧 data 步 labeling 后,该变量的 label 还是不是矢志不渝地存在?

PROC MEANS DATA= auto2; RUN;

没有问题,label 依然存在。

很好理解吧,给 variable 进行 labeling,我们可以更确切地理解该变量的含义。

creating and using value labels

要对变量的各种取值进行 labeling,坦率地说,用 proc format,有两种方式都可以实现,都拿来吧你!

方式一:借助 value statement

等不及了,先看 code:

PROC FORMAT;    VALUE forgnf        0= "domestic"        1= "foreign"    ;    VALUE $makef        "AMC"= "American Motors"        "Buick"= "Buick (GM)"        "Cad."= "Cadillac (GM)"        "Chev."= "Chevrolet (GM)"        "Datsun"= "Datsun (Nissan)"    ; RUN; PROC FREQ DATA= auto2;    FORMAT foreign forgnf.           make $makef.;    TABLES foreign make; RUN;

显而易见,foreign 的 0、1 数值取值在 display 时被字符串标签替代,make 的字符串取值被更详细的 label 取代。这里值得指出来的是,**我们注意到:**字符串变量 make 有 7 种分类取值,而在最后只有其中的 5 种被 labeling,剩余未 labeling 的取值仍然保持原 value 显示;此外,注意到 format statement 中每种 format 后都有个 . ,为啥加这个?其实是为了让 SAS 清楚地分辨变量名和 format 的名字。

以上,出现了对数值取值、字符串取值的 character labeling,我能不能对字符串取值作 numeric labeling?

上 code:

proc format;    invalue fmtgrdn        "Male"= 1        "Female"= 2; run; data xx1;    length sex $10;    sex= "Male"; output;    sex= "Female"; output; run; data xx2;    set xx1;    sexgrdn= input(sex, fmtgrdn.); run;

当然是可以的。这里要提醒大家注意:我们使用了 invalue statement 和 input function。

方式二:借助 proc format input control data sets(cntlin)

讲方式二之前,我们先看下我们上面生成的 fmtgrdn format 的具体情况:

proc format lib= work fmtlib; run;

我这里展示的是,我的 work library 中所有已 define 的 format,为什么全部拿出来展示?因为实际上,包含了 numeric values -> character labels,character values -> character labels 以及 character values -> numeric labels 的情况。我们通过认真理解这些 format 的内在逻辑,非常有助于我们理解第二种 labeling 的方式,即通过 SAS 数据集来生成 format。

我们要 produce 与以上逻辑类似的数据集,上 code:

data scale;    input begin: $char2. end: $char2. amount: $char4.;    datalines;        0   3    0%        4   6    3%        7   8    6%        9   10   8%        11  16   10%    ; run; data ctrl;    length label $11;    set scale(rename= (begin= start amount= label)) end= last;    retain fmtname "PercentageFormat" type "n";    output;    if last then do;        hlo= "O";        label= "***ERROR***";        output;    end; run;

我们借助官方文档中的这个例子来说明 PROC FORMAT input control data sets 的格式要求(如上)。

proc format library= work cntlin= ctrl; run; proc format lib= work fmtlib;    select percentageformat; run;

生成的 format 如下:

值得好好理解体会。

proc format library= work;    invalue evaluation        "O"= 4        "S"= 3        "E"= 2        "C"= 1        "N"= 0    ; run; data points;    input EmployeeId $ (Q1-Q4) (evaluation., +1);    TotalPoints= q1+q2+q3+q4;    datalines;        2355 S O O S        5889 2 . 2 2        3878 C E E E        4409 0 1 1 1        3985 3 3 3 2        0740 S E E S        2398 E E   C        5162 C C C E        4421 3 2 2 2        7385 C C C N    ; run; proc print data= points; run; proc report data= work.points nowd headskip split= "#";    column employeeid totalpoints totalpoints= Pctage;    define employeeid / right;    define totalpoints / "Total#Points" right;    define pctage / format= PercentageFormat12. "Percentage" left;    title "The Percentage of Salary for Calculating Bonus"; run;

这是一个非常有意思的例子,里面很值得细细琢磨。

其实,还有很多值得注意的细节,限于篇幅,我们不能在短短一篇推送里面面俱到,期待以后的推送😬


SAS Training 002 - 聊一聊贴标签 labeling的评论 (共 条)

分享到微博请遵守国家法律