SAS Base编程基础。 第4课:创建SAS数据集

在上一篇文章中,我们学习了如何读取外部原始数据。 今天,我们将熟悉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变量创建一个详细的列:

  1. 如果Lead_Time变量的值小于1,则“详细信息”列的值小于1年。
  2. 如果Lead_Time变量的值在1到2的范围内(包括边界),则“详细信息”列的值为1-2年。
  3. 如果Lead_Time变量的值在2到3的范围内(不包括2),则“详细信息”列的值为2-3年。
  4. 如果Lead_Time变量的值在3到4的范围内(不包括3),则“详细信息”列的值为3-4年。
  5. 如果Lead_Time变量的值在4到5的范围内(不包括4),则“详细信息”列的值为4-5年。
  6. 在所有其他情况下,“详细信息”列的值均高于5年。

您可以通过多种方式创建详细的列,例如,最简单也是最明显的选择是使用条件处理。 可以使用以下运算符实现它:

  1. 如果是其他
  2. 否则
  3. 选择时

对于大量数据,使用后两个选项更为有效。

 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课程的结构:

已经发表的文章:

  1. SAS BASE编程基础。 第一课
  2. SAS BASE编程基础。 第2课。数据访问
  3. SAS BASE编程基础。 第3课。读取文本文件。
  4. 您刚刚学习了第四课。

在以下文章中,我要重点介绍诸如在SAS Base中合并表(合并,设置),条件处理,循环,SAS函数,创建自定义格式,SAS宏,PROC SQL之类的问题。

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

Source: https://habr.com/ru/post/zh-CN426765/


All Articles