SAS 9.4 Base Programming – Performance Based Exam

SAS编程基本概念

1、SAS逻辑库

  SAS逻辑库是一个或多个SAS文件的集合,用于组织、查找和管理SAS文件。

2、逻辑库引用名

  在定义SAS逻辑库时需要指定逻辑库引用名,临时逻辑库WORK除外。
SAS逻辑库 用名的命名规范如下:
 最大长度是8个字符。
 必须以字母(从A到Z,大小写均可)或下划线(_)开始。
 可以是数字(0-9)、字母和下划线(_)的任意组合。

3、逻辑库引擎

  SAS逻辑库引擎是SAS软件和SAS逻辑库之间的接口软件组件,每个SAS逻辑库都关联一种逻辑库引擎。
  逻辑库引擎可分为原生逻辑库引擎接口逻辑库引擎

4、SAS数据集命名

数据集名称遵守SAS命名规则:
 最大长度为32字符。
 必须以字母(从A到Z,大小写均可)或下划线(_)开始。
 可以是数字、字母和下划线(_)的任意组合。

5、变量属性

  SAS数据集变量的属性包括变量名、类型、长度、输出格式(format)、输入格式(informat)和标签(label)。
每个变量的变量名必须遵守SAS命名规范:
 最大长度为32字节。
 必须以字母(从A到Z,大小写均可)或下划线(_)开始。
 可以是数字、字母和下划线(_)的任意组合。
  变量的长度与类型有关。字符变量的长度可以在定义时给出,否则其长度为第一次赋值时值的长度,最大长度可到32K。数字型变量的默认长度是8个字节,也可以指定不同的长度。
  格式(format)会影响数据值写出的方式。
  输入格式(informat)指定数据值以特定的格式读入,从而成为标准的SAS值。在读取包含字母或其他特殊字符的数字值时必须使用输入格式。
  变量都可以有标签(label)。标签通常是描述该变量的文本,最大长度为256个字符。

DATA步读取数据

原始数据一般分为字符和数值两种类型,数值数据又分为标准数值数据和非标准数值数据。
标准数据是由字符或者数值组成的可以被列表、列、格式化、命名输入方式读入的数据,如Male,1166.42。
非标准数据只能在输入格式的帮助下读入的数据。如非标准的数值数据,可能包含逗号,空格等符号。日
期和时间数值。十六进制和二进制数值。
标准数值数据只包含数字,小数点或负号。
非标准数值数据则包含其它的特殊字符,如千分号,美元符号等。

1、DATA步处理

  DATA步由一组SAS语句组成。首先,会由DATA语句创建并命名SAS数据集;然后SAS会编译并检查其语句的语法,如果语法正确,这些语句会被执行。在DATA步中可以使用DATALINES直接输入数据或通过INFILE语句指定原始数据文件。
下面给出了一个典型的DATA步读取外部文件的处理流程:、
(首先创建数据集)
编译DATA步中的SAS语句并检查语法。
创建输入缓冲区、程序数据向量PDV(Program Data Vector)和数据集描述信息。
从DATA语句开始执行。
将PDV中所有变量值(除自动变量NERROR)置为缺失值。
判断是否有数据要读入?有数据要读入,进行下一步。如果没有,关闭数据集。
将数据读入输入缓冲区,并赋值给PDV中的变量。
执行其他可执行语句。
将观测写入SAS数据集。
返回DATA步开始下一个迭代,从第3步开始。

2、读取外部文本文件中的数据(初级)

关于input的columninput (列输入)和listinput (列表输入)
简单来说:列输入就是严格按照变量指定的长度进行数据读取,忽略分隔符;列表输入就是根据规定的分隔符(默认是空格)按照变量的顺序读取数据,多个空格按照一个处理,遇到空格即停止。

使用DATA步读取外部文件中数据的基本形式如下:

DATA 数据集名称;
    INFILE 数据文件位置;
    INPUT 变量列表;
RUN;

FILENAME 文件引用 外部文件|外部文件存储位置;

1) FILENAME语句指定到单个文件的文件引用:
filename invtfile 'c:\sas\data\inventory.dat':指定一个文件的位置
data saslib.Inventory;
     infile invtfile;
     input Product_ID $ Instock Price;
run;
 2) FILENAME语句指定到一组外部文件存储位置的文件引用:指定一个文件夹的位置
filename extfiles 'c:\sas\data';
data saslib.Inventory;
     infile extfiles(inventory);
     input Product_ID $ Instock Price;
run;

列表输入方式
列表输入(List Input)用于读取原始数据记录中每个字段由至少一个分隔符隔开,并且数据值中不包含该分隔符的原始数据。
DATA 数据集; INFILE 文件引用; INPUT 变量1 <$> <变量2 <$> …>; RUN;
上述的列表输入代码存在如下限制:
使用列表输入时,字符变量长度默认为8个字节。当输入数据长度超过8个字节时,从输入缓冲区读入PDV的数据值会产生截断。这个问题可以通过在INPUT语句之前使用LENGTH语句指定该变量的长度或其他方式来解决。
SAS遇到空格时会停止读入当前数据值,这样SAS就不能处理原始数据记录中的数据值包含空格的情况了。
 原始数据中必须使用占位符(.)来表示该数据值为缺失值。

LENGTH 语句
通常在变量第一次出现时程序会根据上下文环境确定其长度。可以在INPUT语句前通过LENGTH语句明确指定变量长度。 LENGTH 变量1 <$>长度 <变量2 <$>长度 …>;

DLM选项
当原始数据中数据记录的数据值未使用空格,而是使用其他分隔符时,需在INFILE语句中使用DLM=选项,告诉SAS读入数据时需要使用的分隔符。 infile extfiles(inventory_dlm) dlm=',';
两个连续DLM指定的分隔符会被当作一个分隔符处理,若分隔符之间是空格,则空格会当作缺失数据被读入变量写进数据集。

DSD选项
指定选项DSD后,如果数据值是由引号引起来的,可以将数据值中的分隔符当成是数据值的一部分读入,字符值中的引号在读入PDV时会被删除。DSD选项将默认的分隔符设置为逗号,还改变了使用列表输入时SAS处理分隔符的方式,比如,如果有两个连续的逗号,将被当作缺失值。 infile extfiles(customer_dsd) dsd;
选项DSD还可以和其他选项(例如DLM=和DLMSTR=)一起使用。DLM=在上面介绍过,DLMSTR=用于指定分隔数据值的字符串。

按列输入方式
使用列输入时一定要注意指针的位置,此时不再是空格为分隔符了,以指针具体位置读取数据
当原始数据记录中的数据值在每条记录中占据相同的列时,可使用按列输入的方式。按列输入(Column Input)可以读取固定列的数据。
该读入方式的INPUT语句基本形式如下: INPUT 变量1 <$> 开始列<-结束列> <变量2 <$>开始列<-结束列> …>;

input Customer_ID $ 1-4  Name $ 6-19 Address $ 21-37 City $ 39-51 State $ 53-54 ;

在上述形式中:

  • 变量名后有$表示该变量为字符型变量。
  • 开始列-结束列指定变量在原始数据记录中所处的位置。
  • 变量长度由为该变量指定的列数确定,可以超过8个字节。
  • 按列输入可读入包含空格的数据值。
  • 可以处理数据中的缺失值,不需要使用占位符。

格式化输入方式
使用格式化输入时一定要注意指针的位置,此时不再是空格为分隔符了,以指针具体位置读取数据
即在INPUT语句中提供特殊的指令,以便SAS正确地读取原始数据记录中的数据值。这些特殊指令称为输入格式(Informat)。格式化输入组合了按列输入特征和读取非标准化数字或字符值的能力,保证数据值可正确地从原始数据记录中读入。
对单个变量,格式化输入的INPUT语句的基本形式如下: INPUT 变量 <$> 输入格式;

常用数字和字符输入格式


image.png

常用的SAS日期、时间、日期时间输入格式


image.png

带修饰的列表输入方式
使用带修饰的列表输入方式,存在格式化输入的情况,只要格式后加上修饰符,SAS仍然以分隔符读取数据
&修饰符(ampersand format modifier):使用列表输入时,该修改符能够读入数据值中包含一个或多个嵌入空格的字符值,并指定字符的输入格式。SAS读入数据直到遇到两个连续的空格、或达到所定义的数据长度或输入行结束才停止。&修饰符解决了使用列表输入方式读取数据值中包含嵌入空格的问题,但要求该包含空格的数据值与下一个数据值之间至少间隔两个空格。
:修饰符(colon format modifier):使用列表输入时,该修改符可以在变量名后指定输入格式。SAS读入数据直到遇到空列、达到所定义的数据长度(对字符型变量来说)或输入行结束才停止。:修饰符可以读取超过8个字节的字符数据和包含特殊字符的数字字符。
~修饰符(tilde forat modifier):可以读入并保持数据值中的单引号、双引号和分隔符。

命名输入方式
命名输入(named input)读取包含变量名、等于符号和变量值的输入数据,例如Name= Willam。
命名输入的基本形式如下: INPUT 变量1= <$> <变量2= <$> …>; input Customer_ID $ Name= $ Age=;
一旦INPUT语句开始使用命名输入方式,接下来的数据值则必须也是命名形式。

混合输入方式
混合输入方式,存在格式化输入的情况,只要格式后加上修饰符,SAS仍然以分隔符读取数据,若存在格式化未加修饰符,则整个数据以指针位置读取

3、读取外部文本文件中的数据(高级)

在创建SAS数据集时,根据数据文件的格式,经常会需要使用更加高级的特征来正确有效地将原始数据文件的记录(或行)转换为数据集。例如:

  • 对原始数据记录中的数据长度不够INPUT语句中所有变量读取的情况进行处理;
  • 在创建SAS数据集的观测前先测试条件是否成立;
  • 在单条数据记录中创建多个观测;
  • 从多个原始数据记录中创建单条观测;

INFILE语句的高级选项

  • FLOWOVER:INPUT语句会读入下一条记录到输入缓冲区中,给当前PDV中未赋值的变量赋值。
  • MISSOVER:会在DATA步的本次迭代中阻止INPUT语句读入原始数据的下一条记录,并将PDV中所有未赋值的变量保持为缺失值(PDV中变量未赋值时就为缺失值)。当原始数据记录中的最后一个或多个字段没有值,并且希望SAS将对应的变量置为缺失值时使用MISSOVER。(针对一行数据最后的数据不存在时)
  • TRUNCOVER:也会阻止INPUT语句读入原始数据的下一个记录,但对于当前正在读入的变量,当输入缓冲区中的数据长度少于当前变量要求的长度时,则将当前输入缓冲区中的数据赋值给PDV中的该变量。所有未赋值的变量置为缺失值。(针对列输入时某个数据长度超过该变量定义长度的情况)
  • STOPOVER:DATA步的执行会停止。当INPUT语句在当前输入行找不到所有数据值时,如果在INFILE语句中使用选项STOPOVER,SAS会停止执行该DATA步。

MISSOVER与TRUNCOVER的不同之处在于,如果当前变量没有读到要求长度的数据,MISSOVER会将当前变量的值也置为缺失值。(MISSOVER仅在列输入时,未达到要求长度的数据会被设为缺失,在列表读入时不会出现这种情况)

若在列输入中加入MISSOVER,如果指针到了一行的结尾,仍然没能读入满足变量长度的数值,就会将该变量变缺失。解决方法:可以再加入pad选项,pad选项数据后面填上空格,使得每行的长度相同,默认lrecl=256。
若在列表输入中加入MISSOVER,不会像列输入那样将最后的变量变缺失。
关于PAD,pad固名思义,意思是将数据行的后面部分填上空格,这样就使得数据行变长,不致于让input指针在读取短数据行时到达数据行结尾从而跳行。

系统选项LRECL和INFILE选项PAD
选项LRECL为系统选项,指定用于读写外部文件的默认逻辑记录长度。
PAD和NOPAD选项控制SAS是否使用空格对从外部文件读入的记录进行填充,使其达到选项LRECL=指定的长度。默认设置为NOPAD。

INPUT语句的行控制符和行保持符

  • 行保持符
  • 行指针控制

通过IMPORT过程读取外部文件数据

IMPORT过程的导入数据的基本形式如下:

PROC IMPORT
    DATAFILE=文件名|文件引用 | DATATABLE=表名 #DATAFILE=指定输入文件的完整路径和文件名,或文件引用。
    DBMS=数据源标识符
    OUT=数据集名称;
RUN;

1、读取CSV文件 DBMS = CSV

2、读取 Microsoft Excel 工作薄 DBMS = XLSX

SAS程序错误及处理

单个数据集处理(一):如何选取部分变量

1、选项KEEP=和DROP=和KEEP和DROP语句

先来理解一下它们在执行过程中的不同之处。在DATA步中,SET语句会将数据读入到程序数据向量PDV中。在SET语句中使用数据集选项时,只有选取的变量才会被读入到PDV,最后写入新数据集。而使用KEEP和DROP语句来选取变量时,SET语句会将原数据集中的所有变量读入到PDV,然后再通过相应的KEEP和DROP语句进行选取并写入新数据集。所以数据集选项KEEP=和DROP=会控制读入程序数据向量PDV中的变量,使用数据集选项通常会更有效率。

Access and Create Data Structures

Create temporary and permanent SAS data sets.

1、DATA + SET语句

/*创建临时数据集*/
data ;
  set sashelp.class;
run;

/*一次创建多个数据集*/
data class1 class2;
  set sashelp.class;
run;

/*不生成数据集*/
data _NULL_;
  set sashelp.class;
run;

2、SQL+CREAT语句

/*创建一个和SASHELP.CLASS一样的数据集*/
proc sql;
  creat tmp as
  select * 
  from sashelp.class;
quit; 

Investigate SAS data libraries using base SAS utility procedures.

1、Use a LIBNAME statement to assign a library reference name to a SAS library.

LIBNAME语句访问DBMS数据文件语法参考卡片
LIBNAME语句访问PC文件语法参考卡片
/*针对Base引擎,engine-name可以省略*/
Libname mydata "D:\SASdata";  要求: D:\SASdata目录必须已经存在

/*用libname输入xlsx多个sheet的数据集*/
libname myxlsx excel 'INPUTxlsx.xlsx';
run;

读xlsx的第3个sheet;
感觉70题上面的方法太老了,这样也是可以的:

libname myxlsx xlsx 'input01.xlsx';
proc contents data=myxlsx._all_;run;  

这样可以将所有myxlsx上面的数据集内容打印出来

proc print data = myxlsx.'SHEETBB$'n;
run;

从上面打印出来的内容中查看你每个表的名字,就可以打印某一个表啦

2、Investigate a library programmatically using the CONTENTS procedure.

  • detials|nodetials(缩写NODS):用于控制显示结果的详尽程度。前者将显示上述的全部内容,后者则仅显示有关变量信息的部分。默认设置: detials(WARNING: 选项 NODS 只能与 _ALL_ 一起使用。)
  • varnum :要求将变量按照其在数据集中的排列顺序而非字母顺序显示。
  • short :有关变量信息部分仅显示变量名称,不显示变量属性。
  • out= :将输入数据集中有关变量的信息存储到指定的数据集中。
  • noprint :禁止程序运行结果在output窗口的输出显示。
/*输出数据集sashelp.class的信息,保存到数据集a中*/
proc contents data=sashelp.class out=a;
run;

Access data.

1、Access SAS data sets with the SET statement.

2、Use PROC IMPORT to access non-SAS data sources.

PROC IMPORT语法参考卡片
  • Read delimited and Microsoft Excel (.xlsx) files with PROC IMPORT
/*PROC IMPORT读入ecxel文件到work逻辑库*/
filename myexcel '***.xlsx';
proc import datafile = myexcel out = work.myexcel 
  dbms = excel replace;
  getnames = yes;   # xlsx文件不能用guessingrows = max;
run;

proc import datafile = '***.xlsx' out = work.myexcel 
  dbms = excel replace;
  getnames = yes;
  guessingrows = max;
run;

/*PROC IMPORT读入CSV文件到work逻辑库*/
filename mycsv '***.csv';
proc import datafile = mycsv out = work.mycsv
  dbms = csv replace;
  getnames = yes;
  guessingrows = max;
run;

/*PROC IMPORT读入TXT特殊字符分隔得文件到work逻辑库*/
/*制表符分隔,二进制为‘09’x*/
filename mytxt1 '***.txt';
proc import datafile = mytxt1 out = work.mytxt1
  dbms = dlm replace;
  delimiter = '09'x;
  getnames = yes;
  guessingrows = max;
run;

/*空格分隔,二进制为‘20’x*/
filename mytxt2 '***.txt';
proc import datafile = mytxt3 out = work.mytxt2
  dbms = dlm replace;
  delimiter = '20'x;
  getnames = yes;
  guessingrows = max;
run;

/* ‘#’分隔符*/
filename mytxt3 '***.txt';
proc import datafile = mytxt3 out = work.mytxt3
  dbms = dlm replace;
  delimiter = '#';
  getnames = yes;
  guessingrows = max;
run;

Combine SAS data sets.

1、Concatenate data sets.

/*创建测试数据集*/
data class1(keep = name sex) class2(keep = age height weight);
  set sashelp.class;
  output class1;
  output class2;
run;

/*横向连接*/
data class;
  set class1;
  set class2;
run;
采用多SET语句横向连接读入时,有几个需要留意的事项:
(1)用多SET语句并接多个数据集,当数据集里面的观测数不等时,SAS读完观测数最少的那个数据及后即停止执行。因此生成的数据集的观测数等于数据集里最少的观测数。
(2)当多个数据集里的变量有重复时,后面的值会覆盖前面的值。

/*众向连接*/
data class;
  set class1 class2;
run;

例题:

  1. The Excel workbook REGIONS.XLS contains the following four worksheets:
    EAST
    WEST
    NORTH
    SOUTH
    The following program is submitted:
    libname MYXLS ’regions.xls’;
    Which PROC PRINT step correctly displays the NORTH worksheet?


Explanation
Answer: D 其实这道题考察的是SAS读取非SAS数据源。 看看答案,四个答案里面差异在于符号$以及E和N的差别。 以下是SAS PAPER里面的解释: 我觉得最关键的就是SAS LIBNAME建立的是以XLS为数据源的逻辑库时,创建了两个数据源,一个是spreadsheet 另外一个是 named range(指定范围的数据)。 我们在输出整个数据时候,应该是spreadsheet,而不是相对指定的范围的数据。制定范围的数据,其实熟悉EXCEL应该知道,就是我们选择部分数据作为我们要分析的对象,用 鼠标拖动即可产生制定范围的数据。

2、Merge data sets one-to-one.

/*创建测试数据集*/
data class1(keep = name sex) class2(keep = name age height weight);
  set sashelp.class;
  output class1;
  output class2;
run;

/*匹配连接*/
proc sort data = class1;
  by name;
run;

proc sort data = class2;
  by name;
run;

data class;
  merge class1 class2;
  by name;
run;

/*MERGE语句实现各种连接类型*/
/*创建测试数据集*/
data class1(keep = name sex) class2(keep = name age height weight);
  set sashelp.class;
  output class1;
  if _n_ in (1, 5, 10, 15) then output class2;
run;

data class2;
  set class2;
  if name = '亨利' then name = '亨瑞';
run;

/*排序准备*/
proc sort data = class1;
   by name;
run;

proc sort data = class2;
   by name;
run;

data class_left;
  merge class1(in = c1) class2(in = c2);
  by name;
  if c1;
run; /*左连接*/

data class_right;
  merge class1(in = c1) class2(in = c2);
  by name;
  if c2;
run; /*右连接*/

data class_inner;
  merge class1(in = c1) class2(in = c2);
  by name;
  if c1 and c2;
run; /*内连接*/

data class_full;
  merge class1(in = c1) class2(in = c2);
  by name;
  if c1 or c2;
run; /*全连接*/
  • 可以同时MERGE多个数据集,对于相同的变量,最后一个数据集里的值会覆盖前一个数据的值。

Create and manipulate SAS date values.

1、Explain how SAS stores date and time values.

  在SAS中可以创建日期常量、时间常量、时间日期常量。这些常量的形式为在单引号或双引号中指定日期或时间,并接着跟随一个D(日期)、T(时间)或DT(日期时间)来说明值的类型。例如,'1jan2013'd、'9:25't、 '01may12:9:30:00'dt。任何引号中包括的前导或尾缀空格都不会影响这些常量的处理。

data tmp;
  date = '01Jan1960'd;
  time = '00:00:00't;
  datetime = '01Jan1960 00:00:00'dt;
run;

SAS采用数值存储日期和时间形式的数据。在默认情况下, SAS系统以0代表1960年1月1日0时。其它日期在SAS系统中被存储为与该日期相差的天数。
例如, 1960年1月3日,在系统中存为2。
2004年1月25日,在系统中存为16095。

2、Use SAS informats to read common date and time expressions.

常用的SAS日期输入格式

3、Use SAS date and time formats to specify how the values are displayed.

常用的SAS日期输出格式
data timea;
  input dd date15.;
  format dd date9.;
  cards;
  1Jan2002
  03 Jan 2003
  15/May/2004
  12-FEB-2005
  17*May* %2006
  1**OCT**2007
  30%sep%//2008
  ;
proc print data = timea;
run;

data timeb;
  input dd mmddyy10.;
  format dd mmddyy10.;
  cards;
01312002
03122003
5 13 2004
4 21 2005
5 25 2006
1/2/2007
3-24-2008
  ;
proc print data = timeb;
run;

Control which observations and variables in a SAS data set are processed and

output.

1、Use the WHERE statement in the DATA step to select observations to be processed.

2、Subset variables to be output by using the DROP and KEEP statements.

3、Use the DROP= and KEEP= data set options to specify columns to be processed and/or output.

Manage Data

Sort observations in a SAS data set.

1、Use the SORT Procedure to re-order observations in place or output to a new dataset with the OUT= option.

PROC SORT语句格式
  • BY语句指定需要排序的变量,数据集将按此变量排序
  • descending选项:表示该选项之后的一个变量按降序对记录排序;若省略引选项,则按升序对记录排序
  • Data=输入数据集,即需要排序的数据集
  • Out=输出数据集,即排序之后的数据集
data account;
  input Company $ 1-22 Debt 25-30 AccNum 33-36 Town $ 39-51;
  cards;
  Paul's Pizza 83.00 1019 Apex
  World Wide Electronics 119.95 1122 Garner
  Strickland Industries 657.22 1675 Morrisville
  Ice Cream Delight 299.98 2310 Holly Springs
  Watson Tabor Travel 37.95 3131 Apex
  Boyd & Sons Accounting 312.49 4762 Garner
  Bob's Beds 119.95 4998 Morrisville
  Tina's Pet Shop 37.95 5108 Apex
  Elway Piano and Organ 65.79 5217 Garner
  Tim's Burger Stand 119.95 6335 Holly Springs
  Peter's Auto Parts 65.79 7288 Apex
  Deluxe Hardware 467.12 8941 Garner
  Apex Catering 37.95 9923 Apex
  ;
proc sort data=account out=bytown;
  by town company;
run;

2、Remove duplicate observations with the SORT Procedure.

  使用SORT过程的NODUPKEY可以在对数据集按BY变量进行排序的同时,删除数据集中BY变量值相同的观测。

filename contact 'F:\Data Analysis\SAS\Data&Code\Data\ch2\contact.csv';
proc import datafile = contact out = work.contact 
  dbms = csv replace;
  getnames = yes;
  guessingrows = max; /*注意excel没有这个语句,其它文件都可以*/
run;

proc sort data = work.contact 
    out = fullcontact
    dupout = dup
    nodupkey;
    by name;
run;

Conditionally execute SAS statements.

1、Use IF-THEN/ELSE statements to process data conditionally.

2、Use DO and END statements to execute multiple statements conditionally.

Use assignment statements in the DATA step.

1、Create new variables and assign a value.

  • 选项RENAME=和RENAME语句


    选项RENAME=

    RENAME语句
data baseball;
    set sashelp.baseball(rename = (name = full_name));
    first_name = scan(full_name,1);
    last_name = scan(full_name,2);
run;

data baseball (rename = (name = full_name));
    set sashelp.baseball;
    first_name = scan(name,1);
    last_name = scan(name,2);
run;

data baseball;
    set sashelp.baseball;
    rename name = full_name;
    first_name = scan(name,1);
    last_name = scan(name,2);
run;

SET语句中的数据集选项RENAME=会修改变量名,此时,在编程语句中引用原变量时必须使用新的变量名;如果在输出数据集中使用RENAME=选项或使用RENAME语句,在编程语句引用原变量时必须使用旧的变量名。

  • 赋值语句创建新变量

  • 对多个观测求和:求变量总和、求BY组的总和、RETAIN语句、SUM函数


    求变量总和

    求BY组的总和
data work.shoes_subsidiary (drop = sales);
  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;
RETAIN语句

RETAIN语句求和

  如果Sales中存在缺失值,那么赋值语句中表达式(Total_Sales+Sales)的结果也为缺失值,这样会导致当前及其后所有迭代中Total_Sales的值都为缺失值。
  此外使用RETAIN语句还需要注意的是,如果该变量名仅在RETAIN语句中出现,并且RETAIN语句中未对其赋初值,则该变量不会写入到输出数据集中。反之,如果RETAIN语句中给出了变量初始值,即使该变量仅在RETAIN语句中出现,该变量也会写入输出数据集。
SUM函数

2、Assign a new value to an existing variable.

3、Assign the value of an expression to a variable.

4、Assign a constant date value to a variable.

Modify variable attributes using options and statements in the DATA step.

1、Change the names of variables by using the RENAME= data set option.

2、Use LABEL and FORMAT statements to modify attributes in a DATA step.

  • 当在一个PROC过程步中使用LABEL语句时,仅在该过程步期间该标签与该变量相联系
  • DATA数据步中使用时,标签与变量的联系一直存在所建的数据集中

3、Define the length of a variable using the LENGTH statement.

Accumulate sub-totals and totals using DATA step statements.

1、Use the BY statement to aggregate by subgroups.

2、Use first. and last. processing to identify where groups begin and end.

3、Use the RETAIN and SUM statements.

Use SAS functions to manipulate character data, numeric data, and SAS date

values.

1、Use SAS functions such as SCAN, SUBSTR, TRIM, UPCASE, and LOWCASE to perform tasks such as the tasks shown below.

较重要的字符函数

SCAN:
【功能】从字符表达式s中搜取给定的n个单词
【类别】 字符函数
【语法】

  1. scan(s,n) n为正数时,从字符s末尾提取n个字符
  2. scan(s,n) n为负数时,从字符s开始提取n个字符
  3. scan (s,n<,list-of-delimiters>) 空格和参数指定的分隔符同作为分隔符判断单词,返回分隔后的第n个单词
    如果不指定,则按照常用的分隔符拆分,默认分隔符为:空格 .
    注意事项:
  4. 如果缺失指定的生成变量的长度,系统默认长度为200.
  5. 如果|n|=0或大于字符s的长度,则该函数返回空格。

2、Use SAS numeric functions such as SUM, MEAN, RAND, SMALLEST, LARGEST, ROUND, and INT.

SUM:求和
MEAN:均数
RAND:随机数函数
SMALLEST(k,x1,x2,x3):从小到大排序,第k个
LARGEST(k,x1,x2,x3):从大到小排序,第k个
ROUND:四舍五入
INT:取整

data A (drop = i tmp:);
    array tmp{100};
    do i = 1 to 100;
        tmp{i} = rand('normal',5,2);
    end;
    average = mean(of tmp1 - tmp100);
    total = sum(of tmp:);
    min = smallest(1,of tmp:);
    max = largest(1,of tmp:);
    round_min = round(min);
    round_max = round(max);
    int_min = int(min);
    int_max = int(max);
run;

3、Create SAS date values by using the functions MDY, TODAY, DATE, and TIME.

TODAY:获取当前日期,不要参数  
DATE:获取当前日期,不要参数  
MDY:生成yr年m月d日的SAS日期值
WEEKDAY(date) 由SAS日期值date得到星期几,“1”表示星期一

data B;
    today = today();
    date = date();
    mdy = mdy(4,24,2021);
    year = year(today);
    month = month(today);
    day = day(today);
    weekday = weekday(today);
run;

4、Extract the month, year, and interval from a SAS date value by using the functions YEAR, QTR, MONTH, and DAY.

YEAR(date) 由SAS日期值date得到年
QTR(date) 由SAS日期值date得到季度值
MONTH(date) 由SAS日期值date得到月
DAY(date) 由SAS日期值date得到日

data C;
    today = today();
    date = date();
    year = year(today);
        qtr = qtr(today);
    month = month(today);
    day = day(today);
run;

5、Perform calculations with date and datetime values and time intervals by using the functions INTCK, INTNX, DATDIF and YRDIF.

INTNX(interval,from,n) 计算从from开始经过n个interval间隔后的SAS日期。其中interval 可以取'YEAR'、 'QTR'、 'MONTH'、 'WEEK'、 'DAY'等。
比如,INTNX('MONTH','16Dec1997'd, 3)结果为1998年3月1日。注意它总是返回一个周期的开始值。 

INTCK(interval,from,to) 计算从日期from到日期to中间经过的interval间隔的个数。 其中interval取'MONTH'等。
比如, INTCK('YEAR', '31Dec1996'd, '1Jan1998'd)计算1996年12 月31日到1998年1月1日经过的年间隔的个数,结果得2,尽管这两个日期之间实际只隔1年。

DATDIF:根据指定的日期返回两个日期之间的天数。

Use SAS functions to convert character data to numeric and vice versa.

1、Explain the automatic conversion that SAS uses to convert values between data types.

Automatic Numeric-to-Character Conversion
数字数据到字符数据的自动转换非常类似于character-to-numeric conversion。只要在character context中使用数值数据值,它们就会转换为字符值。
例如,如果您这样做,变量Site的数值将转换为字符值

  • 将数值赋值给先前定义的字符变量,例如字符变量SiteCode: SiteCode=site
  • 将数值与需要字符值的操作符一起使用,如串联操作符:SiteCode=site||dept
  • 在需要字符参数的函数中指定数值,例如SUBSTR函数:Region=substr(site,1,4)
    具体地说,SAS以BEST12. 格式写入数值,得到的字符值是右对齐的。此转换发生在对任何操作符或函数赋值或使用该值之前。自动数字到字符的转换可能会导致意想不到的结果。例如,假设原始数值的数字少于12位。得到的字符值将有前导空格,这在执行操作或函数时可能会导致问题。
    Numeric-to-character conversion还导致将一条消息写入SAS日志,表明已经进行了转换。

最好不要依赖自动转换。当您知道必须将数值数据转换为字符数据时,可以通过在SAS程序中包含PUT函数来执行显式转换。
Automatic Character-to-Numeric Conversion

2、Use the INPUT function to explicitly convert character data values to numeric values.

Input function:Explicit Character-to-Numeric Conversion
例子:您需要通过将字符变量PayRate乘以数值变量Hours来计算employee salaries。


你可以使用下面的代码:

data hrd.newtemp;
    set hrd.temp;
    Salary=payrate*hours;
run;

您知道提交这个数据步骤将导致automatic character-to-numeric conversion,因为字符变量PayRate是在数字环境中使用的。可以使用INPUT函数显式地将PayRate的字符值转换为数字值,而不是让它自动转换。
General form, INPUT function:
INPUT(source,informat)

  • source指出要转换为数值的字符变量、常量或表达式
  • 还必须指定一个数字的informat,如下例所示: input(payrate,2.),因为这个source应该是以数字的形式存在,虽然他是一个字符型变量。
    在选择informat时,一定要选择能够读取值的形式的数字informat。


例如:Test=input(saletest,comma9.);
所以开始那个例子也可以用下面的代码实现:
data hrd.newtemp;
    set hrd.temp;
    Salary=input(payrate,2.)*hours;
run;

请注意,当您使用INPUT函数时,SAS日志中不会出现转换消息。

3、Use the PUT function to explicitly convert numeric data values to character values.

put function: numeric-to-character conversions
PUT(source,format)
请注意,INPUT函数需要informat,而PUT函数需要format。
General form, PUT function:
PUT(source,format)

  • source*指定要转换为字符值的数值变量、常数或表达式
  • 还必须指定与source数据类型匹配的format,如本例所示: put(site,2.)
    注意:
  • PUT函数总是返回一个字符串。
  • PUT函数返回用format.编写的source
  • 格式必须与source的类型一致。
  • 数字格式右对齐结果;字符格式左对齐结果。表示如果是数字转换成字符,则转化后是右对齐,在前面补充空格。
  • 如果使用PUT函数创建一个以前没有标识的变量,它将创建一个长度等于format宽度的字符变量。
    例子:
proc import file = 'temp.csv' out = temp dbms = csv replace;run;
data newtemp;
   set temp;
   Assignment1=site||'/'||dept;
   Assignment2 = put(site, 10.);
   Assignment3=put(site,2.)||'/'||dept;
run;

结果:

  • 可见,Assignment1中,数字是右对齐的,Assignment1的总长度17=12长度的site+1长度的/+4长度的dept
  • Assignment2,长度为指定的format,即10,且是右对齐的
  • Assignment3,就是用put语句把site转化成字符型,且其长度是2

Process data using DO LOOPS.

1、Explain how iterative DO loops function.

2、Use DO loops to eliminate redundant code and to perform repetitive calculations.

3、Use conditional DO loops.

4、Use nested DO loops.

Restructure SAS data sets with PROC TRANSPOSE.

1、Select variables to transpose with the VAR statement.

2、Rename transposed variables with the ID statement.

3、Process data within groups using the BY statement.

4、Use PROC TRANSPOSE options (OUT=, PREFIX= and NAME=).

image.png

OUT=:转置后数据集名称
PREFIX=:给转置变量在新数据集中的变量名加前缀
NAME=:转置变量在新数据集中的名字,默认NAME

Use macro variables to simplify program maintenance.

1、Create macro variables with the %LET statement

%LET语句创建宏变量

2、Use macro variables within SAS programs.

引用宏变量

Error Handling

Identify and resolve programming logic errors.

1、Use the PUTLOG Statement in the Data Step to help identify logic errors.

2、Use PUTLOG to write the value of a variable, formatted values, or to write values of all

variables.

3、Use PUTLOG with Conditional logic.

4、Use temporary variables N and ERROR to debug a DATA step.

Recognize and correct syntax errors.

1、Identify the characteristics of SAS statements.

2、Define SAS syntax rules including the typical types of syntax errors such as misspelled keywords, unmatched quotation marks, missing semicolons, and invalid options.

3、Use the log to help diagnose syntax errors in a given program.

Generate Reports and Output

Generate list reports using the PRINT procedure.

Modify the default behavior of PROC PRINT by adding statements and options such as

  • use the VAR statement to select and order variables.
  • calculate totals with a SUM statement.
  • select observations with a WHERE statement.
  • use the ID statement to identify observations.
  • use the BY statement to process groups.

Generate summary reports and frequency tables using base SAS procedures.

1、Produce one-way and two-way frequency tables with the FREQ procedure.

2、Enhance frequency tables with options (NLEVELS, ORDER=).

3、Use PROC FREQ to validate data in a SAS data set.

4、Calculate summary statistics and multilevel summaries using the MEANS procedure

5、Enhance summary tables with options.

6、Identify extreme and missing values with the UNIVARIATE procedure.

Enhance reports system user-defined formats, titles, footnotes and SAS System reporting options.

1、Use PROC FORMAT to define custom formats.

  • VALUE statement
  • CNTLIN= option

2、Use the LABEL statement to define descriptive column headings.

3、Control the use of column headings with the LABEL and SPLIT=options in PROC PRINT output.

Generate reports using ODS statements.

1、Identify the Output Delivery System destinations.

2、Create HTML, PDF, RTF, and files with ODS statements.

3、Use the STYLE=option to specify a style template.

4、Create files that can be viewed in Microsoft Excel.

Export data

1、Create a simple raw data file by using the EXPORT procedure as an alternative to the DATA step.

2、Export data to Microsoft Excel using the SAS/ACCESS XLSX engine.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容