在上
一篇文章中,我们学习了如何读取外部原始数据。 今天,我们将熟悉SET运算符,该运算符可读取标准SAS数据集(SAS数据集),学习如何创建数据片,配置持久属性以及学习一些有用的SAS功能。 我将再次尝试使用尽可能多的示例以最简单的语言来介绍材料。
假设数据以EXCEL格式存储在目录
C:\ workshop \ habrahabr中 。 我们导入电子表格,从中创建一个切片,使用SAS函数创建新的计算列,然后将此数据集分为两部分。
导入电子表格并设置过滤器
excel文件存储在上述目录中,如下所示:
文件片段:
我们应用
PROC IMPORT过程将电子表格转换为SAS数据集:
options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company replace; getnames=yes; run;
从SAS的角度来看,
validvarname = V7选项可设置正确的字段名称:用下划线替换所有无效字符。 变量的命名规则可以在
第1课中找到
。我们在读取外部文件时会立即设置过滤器,例如,我们仅选择不缺少结束日期的那些观察值。 请注意where参数的语法。
options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company (where=(End_Date not is missing)) replace; getnames=yes; run;
让我们详细考虑PROC IMPORT步骤运算符:
数据文件 -定义外部文件的完整路径和名称
Dbms-定义要导入的数据类型。
Out(输出) -用一个或两个级别的SAS名称(库名称和数据集名称)标识SAS输出数据集。
替换 -覆盖现有的SAS数据集。
Getnames-表示PROC IMPORT是否从输入外部文件第一行中的数据值生成SAS变量名。
运行PROC IMPORT步骤并检查LOG:
打印结果SAS数据集:
proc print data=work.company noobs; run;
PROC PRINT过程的输出如下所示:
片段:
同样在SAS UE中,您可以使用“结果”选项卡查看导入的SAS数据集。
读取SAS数据集
读取SAS数据集是在DATA步骤中使用
SET语句实现的:
考虑一下SET语句的一般语法:
SET<SAS-data-set(s) <(data-set-options(s) )> > <options>
如果未在SET语句中指定数据集,则它将从最后创建的SAS数据集中读取观测值。
在SET语句中,您可以指定几个数据集;在这种情况下,SAS数据集将被一个添加到另一个(类似于SQL中的UNION)。
同样,在DATA步骤中,可以有两个SET语句,在这种情况下,表由公共列连接。 例如,您可以在
本文中阅读有关两个SET语句的更多信息。
创建SAS数据集副本的最简单代码如下:
data company1; set company; run;
配置SAS数据集描述符
您可以使用PROC CONTENTS过程检查SAS数据集描述符(
请参阅第2课 )。 在本教程中,我们将使用
PROC DATASETS过程打印描述符组件:
proc datasets library=work nolist; contents data=company order=varnum; quit;
结果片段:
为Travel_Expenses和Budget变量设置恒定格式:
data company; set company; format Travel_Expenses Budget dollar10.2; run;
检查SAS数据集的属性:
proc datasets library=work nolist; contents data=company order=varnum; quit;
创建计算列
可以在《
SAS 9.4函数和CALL例程:参考,第五版》中探讨所有SAS函数。
此外,如果没有合适的功能来执行特定任务,则可以使用
PROC FCMP过程并创建自己的功能。
在本课程中,我们将探讨YRDIF,SUM和CATS的三个功能。
要计算以年为单位的日期差异,我们将使用
YRDIF函数 。
让我提醒您,SAS格式的日期是从1960年1月1日开始的天数(
请参阅第1课 )。 根据提供的数据,我们需要计算执行时间:
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); format Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
请注意,对于Lead_Time变量使用3.1格式,我们将报告(!)中的计算值四舍五入到小数点后一位。 格式运算符
不会更改 SAS数据集中
的值!
结果片段:
接下来,我们计算不含差旅费的工作成本:
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
结果片段:
作为我们任务的一部分,我们在不使用功能的情况下计算工作成本时未考虑差旅费用。 我们的表中没有缺失值,如果变量(Budget或Travel_Expenses)之一具有缺失值,则结果为“任务”。
例如:
创建一个测试数据集:
data test; input Budget Travel_Expenses; datalines; 12345 233 . 345 12543 . ;
计算变量Budget Travel_Expenses的差异
data test; set test; value=Budget-Travel_Expenses; run;
此步骤的结果:
为了获得正确的结果,可以使用
SUM函数。
此功能属于
描述性统计功能的类别。 描述性统计功能
会忽略缺失值。
通过SUM编写代码:
data test; set test; value=sum(Budget,-Travel_Expenses); run;
在这种情况下,步骤的结果如下:
计算的第三列是经理的电子邮件地址。 可以从Manager_FirstName,Manager_LastName列和值
habr .com中“组装”它。
您可以使用
CATS函数将文本值组合为一行。
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
结果片段:
让我们检查创建的数据集的描述符:
proc contents data=work.company1 varnum; run;
处理片段:
注意Email变量的长度,它是200字节;这是CATS函数返回的默认长度。 如果我们检查变量Manager_FirstName和Manager_LastName的属性,我们可以确保8 + 6 +字符串长度'@ habr.com'足以容纳Email变量,即另外9个字节,共23个字节。为什么我要注意这一点? 所有丢失的字符都留有空格,这会影响数据集的大小,并会影响大量数据的性能。
为了显式设置Email变量的长度,必须使用LENGTH运算符:
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
处理片段
考虑到以下条件,根据Lead_Time变量创建一个详细的列:
- 如果Lead_Time变量的值小于1,则“详细信息”列的值小于1年。
- 如果Lead_Time变量的值在1到2的范围内(包括边界),则“详细信息”列的值为1-2年。
- 如果Lead_Time变量的值在2到3的范围内(不包括2),则“详细信息”列的值为2-3年。
- 如果Lead_Time变量的值在3到4的范围内(不包括3),则“详细信息”列的值为3-4年。
- 如果Lead_Time变量的值在4到5的范围内(不包括4),则“详细信息”列的值为4-5年。
- 在所有其他情况下,“详细信息”列的值均高于5年。
您可以通过多种方式创建详细的列,例如,最简单也是最明显的选择是使用条件处理。 可以使用以下运算符实现它:
- 如果是其他
- 否则
- 选择时
对于大量数据,使用后两个选项更为有效。
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='4-5 years'; else detail='above 5 years'; run;
添加一个条件,该条件仅选择那些Detail变量的值不等于“ 5年以上”的观测值。 使用where作为过滤器时,将发生语法错误:
where子句不用于计算列。 要选择我们需要的变量,我们需要一个选择性的IF语句。 它将观测值的输出取消到创建的数据集:
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run;
另请注意,选择性IF语句需要算术运算符。 例如,我们不能这样写:
if detail contains 'above 5 years';
错误将显示在日志中:
配置SAS数据集。
变量Manager_FirstName和Manager_LastName不能出现在新的SAS数据集中。 使用DROP参数可以实现此要求,也可以使用DROP运算符。
data company1 (drop=Manager_FirstName Manager_LastName); set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run;
我们根据给定条件将创建的SAS数据集分为两部分
在一个DATA步骤中,您可以创建多个SAS数据集。 为每个国家/地区创建一个单独的数据集。
例如,要检查“国家/地区”列中的值,可以使用
PROC FREQ过程。
proc freq data=company1; table Country /nocum nopercent; run;
此步骤考虑来自国家(地区)变量的特定值在data =参数指定的SAS数据集中出现多少次。
此步骤的结果如下:
因此,我们将使用OUTPUT运算符和条件处理在一个DATA步骤中创建两个数据集:
data US AU; set work.company1; if Country='AU' then output AU; if Country='US' then output US; run;
运行代码并查看日志:
这是有关读取和配置SAS数据集的简要说明。 在下一篇文章中,我们将向您介绍如何使用MERGE和SET语句组合数据集。
作为PS,我会提醒您SAS BASE课程的结构:
已经发表的文章:
- SAS BASE编程基础。 第一课
- SAS BASE编程基础。 第2课。数据访问
- SAS BASE编程基础。 第3课。读取文本文件。
- 您刚刚学习了第四课。
在以下文章中,我要重点介绍诸如在SAS Base中合并表(合并,设置),条件处理,循环,SAS函数,创建自定义格式,SAS宏,PROC SQL之类的问题。

我很乐意在评论中反馈! 您还希望在文章中看到哪些其他主题?