SAS 创建新变量

SAS  创建新变量

在对SAS数据集进行处理时,经常需要根据原有变量或变量值生成新变量。根据要实现功能的不同,SAS提供了多种方法,例如通过数据集选项RENAME=(RENAME语句)、赋值语句、求和语句等来实现不 同的功能。

1  数据集选项RENAME=和RENAME语句

DATA步中,可使用数据集选项RENAME=或RENAME语句修改 一个或多个变量的名称。跟前面介绍过的数据集选项KEEP=和DROP= 一样,数据集选项RENAME=也可用于DATA语句中的输出数据集和 SET语句中输入数据集。其基本形式如下:

RENAME=(旧变量名-1=新变量名-1 <...旧变量名-n=新变量名-n  >)
RENAME语句的基本形式如下:
RENAME  旧变量名-1=新变量名-1 <...旧变量名-n=新变量名-n  >;

其中:

  • ·旧变量名指定在输入数据集中或当前DATA步中新创建的变量。
  • ·新变量名指定在输出数据集中使用的变量名或变量名称列表。新的变量名仅被写入输出数据集。
  • ·数据集选项RENAME=或RENAME语句可以修改多个变量的名称。 

将数据集saslib.contact中的变量Name重命名为 Full_Name,并将原有Name中的姓和名分开为Last_Name和 First_Name。

下面3段代码分别在SET语句中使用数据集选项RENAME=、在DATA语句中使用数据集选项RENAME=和使用RENAME语句来实现。

代码1:

data  work.contact2_rn;
set saslib.contact  (rename=(Name=Full_Name)); 
First_Name=scan(Full_Name,1); 
Last_Name = scan( Full_Name,2);
run;

代码2:

data  work.contact2_rn  (rename=(Name=Full_Name));
set  saslib.contact;
First_Name=scan(Name,1); Last_Name=scan(Name,2); run;

代码3:

data  work.contact2_rn  ; 
set saslib.contact2; 
rename  Name=Full_Name; 
First_Name=scan(Name,1); 
Last_Name=scan(Name,2);
run;

3段代码中都使用了SCAN函数,将原Name变量中用空格隔开的 姓和名提取到变量Last_Name和First_Name中。注意,在引用原Name变 量进行操作时,代码1使用了新变量名(Full_Name)、代码2和代码3使 用了旧变量名(Name)。这是因为在SET语句中使用选项RENAME= 时,SAS为输入数据集所创建的PDV中的变量名就成为了新变量名,所 以在编程语句中引用原变量时必须使用新的变量名。但是如果在DATA 语句中使用选项RENAME=或RENAME语句,新变量名仅会写入输出数 据集,所以在DATA步的其他语句中引用该变量时,必须使用旧的变量名。

SET语句中使用数据集选项RENAME=、在DATA语句中使用数据集选项RENAME=和使用RENAME语句的比较如下:

  • ·RENAME语句不能用于PROC步,但是数据集选项RENAME=可 以。
  • ·数据集选项RENAME=可以对每个输出数据集的变量单独更改名 称,而RENAME语句修改的变量名称对所有输出数据集都起作用。
  • ·SET语句中的数据集选项RENAME=会修改变量名,此时,在编程 语句中引用原变量时必须使用新的变量名;如果在输出数据集中使用 RENAME=选项或使用RENAME语句,在编程语句引用原变量时必须使 用旧的变量名。

 2 赋值语句创建新变量

DATA步中出现的变量,如果不属于输入数据集的变量,而且也 不是自动变量,SAS则会为其创建新变量,所创建的新变量默认会写入 输出数据集。可以通过前面介绍的数据集选项DROP=、KEEP=、DROP 语句、KEEP语句保留或删除不需要的中间变量。

赋值语句是常见的创建新变量的方法,通常将新变量放在赋值语句 的等号(=)左侧来创建新变量,并同时给该变量赋值。在前面的例子已经看到了使用赋值语句修改已经存在的变量值和创建新变量

数据集saslib.revenue_quarter中存储了公司产品今年不同季 度的销售额,年底要计算全年的总销售额。下面对各季度的销售额(Rev_Q1、Rev_Q2、Rev_Q3和Rev_Q4) 相加得到总销售额Total_Rev,最后使用FORMAT语句修改其输出格式。

data  work.revenue;
set  saslib.revenue_quarter;
Total_Rev  =  Rev_Q1  +  Rev_Q2  +  Rev_Q3  +  Rev_Q4;
format  Total_Rev  DOLLAR10.;
run;

3 对多个观测求和

对数据集进行处理时,经常会需要获得整个数据集中的所有观测或 特定一部分观测中的变量值的总和,例如,公司所有产品的总销售额、 产品在各地区的总销售额等。在DATA步中,可使用求和语句、 RETAIN语句、SUM函数等方式对多个观测中的变量值进行求和。

1.求数据集中变量的总和

求和语句的基本形式如下:

变量+表达式;

其中:

  • ·变量指定累加变量的名称,该变量包含一个数字值。
  • ·表达式是任意的SAS表达式。当迭代中表达式的值为缺失值时,SAS会将表达式的求值结果当作0处理。

读入公司销售数据建立数据集,并计算总销售额。公司所有员工销售数据所在外部数据文件sales.dat的内容如下:

ET001,Kevin  Lee,TSG,$10000
ED002,Faith  May,CSG,$12000
ET004,Jackson  Cook,TSG,$18000
EC002,Hailey  Leonard,CSG,$23000
ED004,Jack  Smith,QSG,$5000

为了让所生成的数据集中的变量Sales和Total_Sales的输出格式同输入格式一样,在DATA步使用FORMAT语句指定变量Sales和Toal_Sales 的格式为DOLLAR10.。

filename  exfiles  "c:\sas\data";
data  saslib.sales;
length  Name  $20;
infile  exfiles(sales)  dsd;
input  Emp_ID  $  Name  $  Dept  $  Sales:COMMA10.;
format  Sales  DOLLAR10.;
run;
data  work.sales_sum;
set  saslib.sales;
Total_Sales+Sales;
format  Total_Sales  DOLLAR10.;
run;
proc  print  data=work.sales_sum  noobs;
run;

2.求每个BY组的总和

前面提到过,SAS会为BY语句中指定的每个变量生成临时变量 FIRST.变量和LAST.变量。在分组数据中,可以使用这两组临时变量计 算每个分组中变量值的总和。

data  work.shoes_subsidiary ;
set  sashelp.shoes  (keep=Region  Subsidiary  Sales);
by   Region  Subsidiary;
if First.Subsidiary  then Total_Sales_Subsidiary=0; 
Total_Sales_Subsidiary+Sales; 
if Last.Subsidiary;
format  Total_Sales_Subsidiary  DOLLAR10.;
run;

proc print data=work.shoes_subsidiary;
run;
  • ·在SET语句中,数据集选项KEEP=指定仅读取输入数据集中的变量Region、Subsidiary和Sales。
  • ·在BY语句中,指定BY变量Region和Subsidiary。要求SET语句中的 数据集已经按照Region和Subsidiary排序。SAS自动生成临时变量 First.Region、Last.Region、First.Subsidiary和Last.Subsidiary。其中 First.Region、Last.Region在本例中未用到。
  • ·因为需要计算各附属品牌的总销售额,所以每次出现新品牌First.Subsidiary为1)时将累加变量,并将Total_Sales_Subsidiary置为0。
  • ·求和语句将对Sales值进行累加,结果存储在Total_Sales_Subsidiary中。
  • ·当Subsidary的值为该分组内最后一个值(Last.Subsidiary为1)时, 才将当前输出PDV中的观测输出,此时Total_Sales_Subsidiary为该品牌 的总销售额。当前输出PDV中的变量为Region、Subsidiary、Sales和 Total_Sales_Subsidiary。
  • ·由于输出观测中的变量Sales为每个分组内最后一个产品的销售额,没有意义,因此在DATA语句中使用数据集选项DROP=指明不将变量Sales写入输出数据集work.shoes_subsidiary。
  • ·此外,FORMAT语句在编译时指定累加变量Total_Sales_Subsidiary的输出格式为DOLLAR10.。

3.使用RETAIN语句保持变量值

 

默认情况下,DATA步中所有变量在每次迭代开始前都会被设置为缺失值。而RETAIN语句中指定的变量则不会,其值会一直保持着,在下次迭代中仍然可以使用。RETAIN语句的基本形式如下:

RETAIN  元素列表1  <初始值1|初始值列表1>  <...元素列表n<初始n|初始值列表n> >;

其中:

  • ·元素列表指定要在历次迭代中保持其值的变量名、变量列表或数组名。
  • ·初始值或初始值列表为其前面的元素指定的初值(为数字或字 符)。

当指定一个初始值时,该初始值被指定为其前面元素列表中的所 有元素的初值。若指定的是初始值列表(多个初始值),SAS会将该列 表中的第一个值指定给第一个元素,第二个值指定给第二个元素,依此 类推。当未指定初始值或初始值列表时,其前面的元素的初始值为缺失值。

基于数据集saslib.sales,使用RETAIN语句和赋值语句计算 公司产品全年总销售额。

示例代码如下:

data  work.sales_retain;
set  saslib.sales;
retain  Total_Sales  0;
Total_Sales=Total_Sales+Sales;
format  Total_Sales  DOLLAR10.;
run;
proc  print  data=work.sales_retain  noobs;
run;

RETAIN语句将Total_Sales的初值设置为0,并告诉SAS在每次迭代 中保持Total_Sales的值。接下来的赋值语句将上次迭代中计算得到的 Total_Sales值与当前观测中Sales的值相加,结果存储在Total_Sales中。  

该例使用的数据saslib.sales中变量Sales没有缺失值。如果Sales中存 在缺失值,那么赋值语句中表达式(Total_Sales+Sales)的结果也为缺 失值,这样会导致当前及其后所有迭代中Total_Sales的值都为缺失值。 读者可在SET语句中使用例3.20中使用的带缺失值的数据集 saslib.sales2,并查看其生成数据集的内容。当数据值中包含缺失值时, 还可以使用SUM函数对变量求和,该函数只会计算非缺失值的和,具体 的接下来会介绍。

此外,使用RETAIN语句还需要注意的是,如果该变量名仅在RETAIN语句中出现,并且RETAIN语句中未对其赋初值,则该变量不会写入输出数据集中。反之,如果RETAIN语句中给出了变量初始值, 即使该变量仅在RETAIN语句中出现,该变量也会写入输出数据集。

4. 使用SUM函数

SUM函数返回非缺失值参数的和。SUM函数的基本形式如下:

SUM(参数,  参数...);

该求和语句等效于RETAIN语句和SUM函数的组合。其中,参数指 定为数字常量、数字变量或数字表达式。如果参数中包含缺失值,且所 有参数都是缺失值,则返回缺失值;若任一参数不是缺失值,则返回非 缺失值参数的总和。与求和语句不同,SUM函数不会保持任何变量的 值,所以如果要想保持的变量,应该使用RETAIN语句。

基于数据集saslib.sales,计算公司产品全年总销售额。 示例代码如下:

data  work.sales_sumfunc; 
set saslib.sales;
retain Total_Sales 0; Total_Sales=sum(Total_Sales,Sales); format Total_Sales DOLLAR10.; run; work.sales_sumfunc 3.22

本次汇总:

1、使用rename对变量重新命名得三种模式

2、利用复制语句创建新的变量 A=x;

3、对数据求和得几种方式:

  1. 变量求和
  2. by语句求和(first.var1 ; last.var1)
  3. retain 语句求和
  4. sum函数求和
posted @ 2019-03-14 10:31  suolilian  阅读(10039)  评论(0编辑  收藏  举报