SAS | 使用SAS数据

 

1 创建和重定义变量

创建和重定义变量,是SAS中最受人欢迎的功能之一,你可以用以下基本形式的赋值语句,来创建和重定义变量:

variable = expression ;

variable 是变量名,可以是新变量或已有变量。expression 可以是常量、另一个变量 或 数学表达式。以下是基本类型赋值语句的示例:

表达式类型 赋值语句
数值常量 qwerty = 10;
字符常量 qwerty = 'ten';
变量 qwerty = oldvar;
加法 qwerty = oldvar + 10;
减法 qwerty = oldvar - 10;
乘法 qwerty = oldvar * 10;
除法 qwerty = oldvar / 10;
求幂 qwerty = oldvar ** 10;

变量qwerty 是字符还是数值,取决于定义它的表达式。而表达式遵循标准的数学运算优先级顺序:先求幂,然后乘除,最后加减,并可以通过括号来改变运算顺序。

 

2 使用SAS函数

使用函数时需要注意几点:

  • 所有函数都必须带括号,即便没有任何参数
  • 参数之间用逗号分隔
  • 参数可以是变量名称、数字、带引号的字符常量、表达式

另外,当涉及变量值时,SAS区分你大小写,这时常使用 UPCASE() 函数,将所有字母转换为大写。

 

2.1 常用SAS字符函数

函数名、语法、定义及示例详见 page89 第三章 3.3节。

 

2.2 常用SAS数值函数

函数名、语法、定义及示例详见 page90 第三章 3.4节。

 

3 IF-THEN语句

3.1 使用if-then语句(单分支)

if-then语句,又称为条件逻辑,用法类似于python中分支结构里的单分支(只有一个真区间)。

语法:if condition then action ;

在条件condition为真时,执行then后面的action语句。condition可以是常量、变量或表达式,通过比较运算符、in运算符等进行比较。
 
比较运算符

符号 助记符 含义
= EQ 等于
^=、~= NE 不等于
> GT 大于
< LT 小于
>= GE 大于等于
<= LE 小于等于
 
IN 运算符

in运算符是将变量值与值列表进行比较。

示例:if model in ('model T', 'model A') then make = 'ford';
 
DO 组合

一个IF-THEN语句只能由一个动作,如果想要执行多个动作,则可以添加关键字DO和END。

do语句将在其后出现直至与之匹配的end语句为止的所有SAS语句视为一个单元。do语句、end语句和它们之间的所有语句一起,被称为do组合。

语法:

if condition then do;
	action1;
	action2;
	……
end;

 
逻辑运算符

IF-THEN语句中condition条件判断,还能包含逻辑运算符ADN、OR及其组合,来进行多个条件的组合判断。

符号 助记符 含义
& AND 所有表达式必须为真
|、! OR 至少有一个表达式为真

示例:if condition1 and condition2 then action ;

 

3.2 使用if-then/else语句分组观测(双分支/多分支)

对观测进行分组的常用方法有:

  • IF-THEN语句
  • SELECT语句
  • PROC FORMAT 生成的用户自定义格式的PUT函数

而创建分组变量的最简单和最常见方法,就是使用一系列IF-THEN语句。并且,通过在IF语句中添加关键字ELSE,可以告知这些语句是相关的,用法类似于Python中的双分支和多分支。
 
IF-THEN/ELSE 语句

基本语法:

if condition then action;
	else if condition then action;
	else if condition then action;

注意,ELSE语句是添加在IF-THEN语句前面,这样的语句可以是无限多个。ELSE语句保证分组的逻辑是相互排斥的,一旦观测满足某个条件,SAS就会跳过不执行该系列其余语句。

有时,ELSE语句系列中的最后一个ELSE会不同,它只包含一个动作而没有TF或THEN。这种ELSE充当默认值的角色,它将执行所有未能满足任何先前的IF语句的观测。但你只能有一个这样的语句,它必须是 IF-THEN/ELSE 系列中最后一个语句。

语法如下:

if condition then action;
	else if condition then action;
	else if condition then action;
	……
	else antion

示例:

if cost = . then costgroup = 'missing';
	else if cost < 2000 then costgroup = 'low';
	else if cost < 10000 then costgroup = 'medium';
	else costgroup = 'high';

 

4 提取数据中的子集(if语句/delete语句)

IF语句

在SAS中,提取数据集中的某些观测而排除其余观测,最常见的方法是 IF 语句和 WHERE 语句。IF语句的基本语法形式如下:

if expression ;

如:if sex = 'f' ;

可以把 IF 语句看成是 IF-THEN语句的特例。其含义是:若表达式为真,则SAS继续执行data步;若表达式为假,则SAS停止处理该观测的后续语句,即该观测不会添加到正在创建的数据集,然后SAS接着处理下一个观测。

简单地理解,可以把IF语句看成是一个开关:

  • if条件为真,开关打开,观测被处理
  • if条件为假,开关关闭,观测不被处理
     
    DELETE语句

与IF语句告诉SAS要哪些观测相反,delete语句告诉SAS不要哪些观测。如果sex变量只包含两个变量且灭有缺失值,则下面两条语句等价。

*if语句;
if sex = 'f';

*delete语句;
if sex = 'm' then delete;

总之,当更容易指定条件包含观测时,取子集用 IF 语句;而在更容易指定条件排除观测时,用 DELETE 语句。

 

5 使用SAS日期

SAS日期是等于 1960.1.1 以来的天数值。关于日期处理,SAS有专门的工具:日期输入函数、输出格式和操作日期的函数。
 
输入格式

可以使用格式化的输入方式,来读取日期型变量,把日期数据转换为 1960.1.1 以来的天数。

示例:input birthday ANYDTDTE9. ; /* ANYDTDTEw是一种特殊的输入格式,能读取几乎任意格式的日期 */

设置输入的默认世纪

当遇到类似 07/04/76 的两位数年份日期数据时,SAS必须判断年份是在那个世纪,是1976,2076,还是其他?系统选项 YEARCUTOFF= 选项指定SAS使用的百年跨度的第一年,可以使用OPTIONS语句修改此值:

示例:options yearcutoff = 1950 ;

上面语句含义是告知SAS,将两位数的日期解释为发生在1950年开始,往后跨度100年,即1950年 ~ 2049年间。

关于日期的更多输入格式,见page100。

此外,一旦使用SAS日期输入格式来读取变量,它就可以像其他数值变量一样,在算术表达式中随意使用。如

duedate = checkdate + 21 ; 也可以在SAS表达式中使用日期作为常量,如:day = '22apr2014'D ;

 

5.1 常用SAS日期函数

示例

age = int(yrdif(birthdate, today(), 'age')) ;

更多函数及其用法,参见page100。

 

5.2 常用SAS日期输出格式

如果打印SAS日期值,SAS将默认打印距离 1960.1.1 的实际天数,但这并不利于观察。所以,SAS提供了多种输出格式用来以不同的格式打印日期。

示例:format birthdate worddate18. ;

更多输出格式及其用法,参见 page100 和 page125。

 

6 保留迭代初始值和累加(retain语句与求和语句)

当SAS读取原始数据时,在DATA步每次迭代开始时会将所有变量设置为缺失值。这些值可以通过input语句或赋值语句来修改,但当SAS返回到data步的开始并处理下一个观测时,它们会被重新设置为缺失值。可以使用RETAIN语句和求和语句来改变这种方式。
 
RETAIN语句

ratain语句,能让变量的值从data步的一次迭代保留到下一个迭代。ratain语句能出现在data步的任何位置,常用的有两种语法形式:

RETAIN  variable-list ;                  *variable-list指所要保留的变量;
RETAIN  variable-list  initial-value ;   *initial-value是为变量指定初始值来代替缺失值进行迭代;

 
求和语句

求和语句不仅保留了上一次迭代的值,还将其值累加到表达式中,适用于将表达式的值累加到变量这种特殊场景。

语法:variable + expression ;

求和语句将表达式的值累加到变量中,同时将变量的 值从data步的一个迭代保留到下一个迭代。需要注意的是,该变量必须是数字,且初始值为0。可以使用RETAIN语句和SUM函数来重写此语句,两者等价。

语法格式:

RETAIN variable 0;
variable = sum(varible, expression);

综合示例如下:

libname zdata "D:\data\sas_file";

data zdata.gamestats;
	infile "D:\data\sas_file\testdata.dat";
	input month 1 day 3-4 team $ 6-25 hits 27-28 runs 30-31;
	retain maxruns;
	maxruns = max(maxruns, runs);
	runstodata + runs;
run;

proc print data = zdata.gamestats;
	title "games total";
run;

 

7 利用数组简化程序(array语句)

数组是相似元素的有序集合

若想对很对变量做同样的事情,你可以编写一系列赋值语句或者IF语句,但更简便的方法是使用数组。在SAS中,数组是一组变量,你可以将数组定义为喜欢的任何变量组,前提是它们全是数值 或 全是字符。SAS中使用data步中的ARRAY语句来定义。

语法:array name (n) $ variable-list ;

其中,name为数组名字,n是数组中的变量个数。在(n)的后面是变量名列表。列表中的变量个数必须等于括号中给出的数字(也可以使用 {} 或 [] 来代替括号),这被称为显式数组。如果变量是字符且之前未定义,则需要加 $ 符号。

变量仅在data步运行时存在,不与数据集一起存储。可以给数组取任何名字,命名规则遵循SAS标准命名规则,但不能与数据集中的变量名相同。

为使用方便,可以使用数组名称和下标,来引用变量,类似于python中的切片,不同的是下标是从1开始,且用的是括号(),如下:

array store(4) macys penneys sears target ;

则store(1)指代变量 macys , store(4)指代变量 target 。

data zdata.songs;
	infile "D:\data\sas_file\songs.dat";
	input city $ 1-15 age wj kt tr filp ttr;
	array song (5) age wj kt tr filp ttr;
	do i = 1 to 5;                              /* DO循环类似于python中的for循环 */
		if song(i) = 9 then song(i) = .;
	end;										/* 结束循环 */
run;

 

8 使用变量名列表的快捷方式

当编写的变量名称列表中变量数量过多时,推荐使用一种快捷方式 —— 变量缩写列表。
 
函数中的缩写列表

在函数中,缩写列表之前必须有关键字OF,如sum(of cat 8 - cat12)
 
数字范围列表

以相同字符开始,并以连续数字结尾的变量,可以时数字范围列表的一部分。只要数字时顺序相连的,就能以任何数字开始和结束。

变量列表 缩写列表
input cat8 cat9 cat10 cat11 cat12; input cat8 - cat12;
 
名称范围列表

名称范围列表取决于SAS数据集中变量的内部顺序或为止,即data步中变量的出现顺序。如下:

data example;
	input y a c h r;
	b = c + r;
run;

要指定名称范围列表,先是第一个变量,接着时连个连字符(--),然后是最后一个变量。

变量列表 缩写列表
put y a c h r b ; put y -- b ;

如果不确定内部顺序,可以使用proc contents中的 POSITION 选项来查找,作用是列出数据集中的变量,并按位置排序。

libaname mydir "D:\data\sas_file";

proc contents data = mydir.diatance position;
run;

 
名称前缀列表

以相同字符开头的变量可以是名称前缀列表的一部分,可以在某些SAS语句和函数中使用。例如:

变量列表 缩写列表
dogbills = sum(dogvet, dogfood, dog_care); dogbills = sum(of dog:);
 
特殊SAS名称列表

有三个可用于任何位置的特殊名称列表:

  • _ALL_:表示数据集中所有变量
  • _CHARACTER_:表示数据集所有字符变量
  • _NUMERIC_:表示数据集中所有数值变量

这些名称列表在要计算某观测的所有数值变量的均值时(MEAN(OF _NUMERIC_)),或列出某观测所有变量的值时(PUT _ALL_)非常有用。

data zdata.songs;
	infile "D:\data\sas_file\songs.dat";
	input city $ 1-15 age wj kt tr filp ttr;
	array new (5) song1-song5;           /* 数字变量列表 */
	array old (5) wj--ttr;               /* 名称范围列表 */
	do i = 1 to 5;
		if old(i) = 9 then new(i) = .;
        else new(i) = old(i);
    end;
    avgscore = mean(of song1-song5);     /* 缩写变量列表 */
run;
posted @ 2020-01-04 14:50  1k-yang  阅读(2162)  评论(0编辑  收藏  举报