【SAS Says】基础篇:update、output、transpose以及相关的数据深层操作

2018-04-04 14:55:58 浏览数 (1)

特别说明:本节【SAS Says】基础篇:update、output、transpose以及相关的数据深层操作,用的是数说君学习《The little SAS book》时的中文笔记,我们认为这是打基础的最好选择。

如果你管着一份10000条的客户数据,有一天,老板拿着一个500人的表告诉你,这表上的500位客户的信息发生了变动,而且变动的变量很不规律,如客户102是收入发生了变动、客户126是职业发生了变动....,叫你在10000条的那个客户主数据中改一下,你怎么办?

用合并?用IF筛选有没有变动?还是一个一个手动去改?都不需要,用update语句更新一下即可。

本节目录:

1. update:用交易数据更新主数据

2. 使用数据集选项

3. 使用in=option追踪观测值

4. output:写多维数据集

5. output:将一个观测值变成多个

6. proc transpose:将观测值转变为变量

7. 使用SAS内置变量


【SAS Says】基础篇:update、output、transpose以及相关的数据深层操作

1. update:用交易数据更新主数据

update语句用来更新大量新数据信息。如上图显示的那样,左边是主数据,右边是交易数据,现在

  • id=2的数据出现了更新,第二个变量变成了2;
  • id=3的数据,第一个变量需要更新成b;
  • 另外数据还要更新的是增加了id=5的数据。

对于这样的更新需求,如何操作?

update语句提供了这种操作,与merge语句一样,按照匹配变量来更新数据,不同点在于:

  • 匹配变量的变量值有唯一性(即不允许出现两个一样id的数据)。
  • 交易数据的缺失值不会改写主数据中存在的值

基本形式为:

DATA master-data-set;

UPDATE master-data-set transaction-data-set;

BY variable-list;

只能指定两个数据集,一个是主数据集一个是交易数据,都需要按照匹配变量排序。且BY变量必须具有唯一性。

例子 一家医院有一份关于病人的主数据。变量依次为病人账户号码、名字、地址、出生日期、性别、保险代码、信息最后被更新的时间。

当有新病人,或其他病人再进医院时,信息会被更新,比如,第一个病人的保险代码被更换了、最后一个病人的缺失数据被填补上、有新病人加入:

下面的代码将这个数据放入一个名为patientmaster的永久数据集中,目录为C盘下的MySASLib:

下面的代码读取交易数据并排序,使用update语句将交易数据更新到主数据中。

输出结果如下:

2. 使用数据集选项

前面已经见过很多选项,SAS语言主要有三种选项:系统选项、语句选项、数据集选项。系统选项有全局影响力,而数据集选项的影响力有限。

系统选项在SAS会话或工作期间都有效,包括center选项,它告诉SAS,center所有的输出。以及LINESIZE=option,设置输出中每一行的最大长度。

语句选项出现在某个语句中,影响某一个数据步或者过程步。

数据集选项影响的只是SAS如何读取和写入一个单个的数据集,可以在数据步(DATA,SET,MERGE,or UPDATE 语句)和过程步(conjuctionwith a DATA=statement option)中使用。用法是,接在数据集名之后,用括号括起来。有些最常见的选项:

  • KEEP=variable-list 告诉SAS保留哪个变量
  • DROP=variable-list 告诉SAS丢弃哪个变量
  • RENAME=(oldvar=newvar) 重命名某个变量
  • FIRSTOBS=n 从观测值n开始读取变量
  • OBS=n 到观测值n停止读取
  • IN=new-var-name 猜一猜,这个是干什么的?

选择并重命名变量 下面是关于KEEP=,DROP=,和RENAME=的数据集选项的例子:

KEEP=,DROP=,和RENAME=的作用与keep、drop、rename很相似。区别在于,后者适用于数据步中的所有变量,而前者仅使用与语句前面的那个数据集。而且,后者仅可以在数据步中使用,而前者除了数据步和过程步,还可以在输入和输出数据集中使用。

用observation number选择观测值 可以使用FIRSTOBS=和obs=来选择读取哪些观测值

这也类似于同名的语句选项和同名的系统选项,语句选项只适用于infile语句,数据集选项是用于数据步和过程步中存在的数据集,而系统选项适用于所有的文件和数据集。如果同时使用同样的系统选项和数据集选项,那么后者将覆盖前者。

追踪观测值 这里提到的选项都是针对现有的变量,而in=option则自己创建一个新变量。这个新变量是临时的,并且有自己在选项中指定。下面的例子,SAS创建了两个临时变量:InAnimals和InHabitat:

该变量只存在于现在的过程步中。

3. 使用in=option追踪观测值

如果将数据集a、b合并,那么在合并的数据集中,你知道那个是来自a哪个是来自b吗?in=option,就是用来追踪原始数据集对应新数据集中的哪个观测值

In=data选项可以被用在数据步中的任何地方——SET,MERGE或者UPDATE——但大部分用在merge语句上,接在要追踪的数据集后面。

下面的数据步创建了一个both数据集,合并两个数据集,state和ounty。并用in=Option创建了两个变量InState和 InCounty:

创建的变量是临时的,只存在于数据步期间。SAS给新变量赋值为0和1。比如county数据集没有关于Louisiana的数据(Louisiana只有parishes,没有counties),因此上例中,两个数据集都含有一个关于Louisiana的观测值,InState变量下的这个观测值为1,InCounty的为0。

Instate和InCounty经常被用在IF或IF-THEN语句中,最为筛选:

Subsetting IF: IF InState=1; IF InCounty=0; IF InState=1 AND InCounty=1; IF-THEN: IF InCounty=1 THEN Origin=1; IF InState=1 THEN State='Yes';

例子 一家运动品厂商有两份数据,一个包括所有客户的数据,一份包括了第三季度订单的数据。现在想要了解哪些客户在第三季度没有任何订单,即可以用in=option选项。客户数据包括客户编号、姓名、地址;订单数据包括客户编号、总价格:

发现没有订单客户的代码如下,数据步中创建了新变量recent,如果出现在客户数据中的观测值没有出现在order中,则recent赋为0,否则赋为1。

结果如下:

4. output:写多维数据集

有时候想在一个数据步中创建多个数据,可以在DATA语句后面多接几个数据集名即可,如下语句告诉SAS创建三个数据集:LIONS、

TIGERS、和 BEARS:

DATA lions tigers bears;

这样仅仅是创建了三个一样的数据集,如果想创建不同的,可以用output语句。

每一个数据步的结尾都有一个暗含的output语句,它告诉SAS在处理下一个观测值之前,将当前的观测值写入输出数据集中。可以用自己的output语句来推翻这个暗含的output语句,基本形式为:

OUTPUT data-set-name;

如果遗漏了数据集名,则将被写入数据步中所有的数据集中去,output可以单独使用,也可以使用在IF-THEN或DO-loop过程中:

IF family='Ursidae' THEN OUTPUT bears;

例子 有一份关于动物园给动物喂食的数据,变量为动物类型、生物学分类、居住区域、喂食是否在早上/下午/两者:

下面的代码创建了两个列表,一个是早上喂食,一个是下午喂食:

日志:

输出报告为:

5. output:将一个观测值变成多个

SAS通常在数据步结尾将一个观测值写入数据中,但可以写入多个观测值,在DO loop中或单独使用output语句。

例子下面的代码阐述如何在DO LOOD语句中使用output语句来产生一个数据集。

这个代码没有INPUT或SET语句,故整个数据步中只有一次迭代——但包括了DO LOOP中的六次循环。由于OUTPUT语句在DO LOOP循环中,因此每次循环都会创建一个观测值。如果没有OUTPUT语句,SAS仅会写入一个观测值,因为结尾处暗含的OUTPUT语句:

例子有一份关于三个电影院的门票销售数据,记录了月份、电影院名称、门票销售额:

现在需要将电影院名作为一个变量、销售额作为一个变量、月份重复三次。

下面的代码使用三次input语句读取同一个原始文件。第一个读取变量month、location和tickets,并用@停留住数据行,接着用OUTPUT语句输出这个观测值。下一个INPUT读取这行后面的名、销售额,并再停留住行。接着读取,但释放行,进入下一个迭代。这个代码用output语句使每一行创建了三个观测值:

结果为:

6. proc transpose:将观测值转变为变量

transpose过程可以转置数据集,将观测值转变为变量或将变量转变为观测值。不部分情况下,将观测值转变为变量,可以使用下面代码:

PROC TRANSPOSE DATA=old-data-set OUT=new-data-set;

BY variable-list;

ID variable;

VAR variable-list;

ID语句 ID语句命名变量,这些变量值将变成新的变量名,ID变量在一个数据集中只能发生一次,如果有BY语句,那么在一个by-group中,变量值必须是唯一的。如果ID变量是数值型变量,新的变量名必须有一个下划线作为前缀(_1 or_2,for example)。如果不适用ID语句,新变量将命名为COL1,COL2等。

VAR语句 VAR语句命名变量,这个变量的变量值是要转置的。

例子 有一份关于儿童棒球联盟选手的数据,包括队名、选手编号、数据类型(salary or batting average)、以及entry:

现在想考察平均打击数与salary之间的关系,首先要将salary和平均打击数变量变量。下面的代码读取数据、按照队伍、选手排序数据,再转置数据:

在proc transpose这步中,BY变量是team和player。ID变量是type,它的值salary和batavg将是新变量名,将要转置的变量entry在VAR语句中指定。注意原来是变量名的entry,现在作为_name_变量下面的变量值。结果为:

7. 使用SAS内置变量

SAS有一些自动变量,这些变量看不到,是临时并不会被储存。但在数据步中,可以任意使用。

_N_和_ERROR_ _N_记录了SAS在数据步中循环的次数,它不一定等于循环次数。因为诸如IF语句就可以使迭代次数与观测数不一致。如果一个观测值的数据出现错误,_ERROR_会被赋值为1,否则赋值为0。错误数据包括无效数据(数值型格式变量却赋为字符串值),转换错误(0作为除数),函数中不合法的自变量(log(0))。

FIRST.variable和LAST.variable 当使用BY语句时,这两个变量才有效。SAS处理一个观测值时,如果某个变量的新变量值是第一次出现,first.variable被赋值为1,其他观测值中被赋为0。LAST.variable是同理的某变量的变量值是最后一次出现时,赋为1,其他赋为0。

例子 有一份不知道绕着镇中心走路比赛的数据,变量为entry number、age group和 finishing time。注意每行不止一个观测值:

第一件要做的事情是为完成情况创建一个新变量。下面代码读取数据,按照finishing time排序,另一个数据步创建新变量place,并赋给它当前的_N_值,print过程产生finishers列表:

第二段代码给出了每个年龄组的第一名:BY语句中自动产生了first.variable,后面的IF语句保留了每个年龄组的第一个观测值,由于数据是按照年龄组agegroup和time排序的,因此第一个观测值就是第一名。结果为:

sas

0 人点赞