SAS中数据集合并技术详解

数据分析领域,经常需要将分散在不同数据集中的信息整合到一个数据集中。本文将探讨在SAS中合并数据集的几种常用方法,包括数据步(Data Step)和PROC SQL。合并数据集时,通常基于共同的字段或标准进行操作。例如,在零售公司中,可能有一个包含产品详情、销售详情和客户详情的每日交易表,以及一个包含产品详情和可用数量的库存表。为了获取库存信息或产品的可用性,需要根据产品代码将交易表和库存表结合起来,并从可用数量中减去已售出的数量。

数据集的合并可以有多种形式,这取决于业务需求和数据集之间的关系。首先,来看一下数据集之间可能存在的几种关系。当第一个数据集中的共同变量(比如变量‘x’)的每个值在第二个数据集中只有一个匹配值时,称之为一对一关系。当第一个数据集中的共同变量(比如变量‘y’)的值在其他数据集中有多个匹配值时,称之为一对多关系。当两个数据集中对于共同变量的相同值都有多个条目时,称之为多对多关系。

在SAS中,可以通过多种方式执行数据集的合并/连接,这里将讨论最常见的两种方式——数据步和PROC SQL。在数据步中,使用MERGE语句来执行连接,而在PROC SQL中,编写SQL查询。首先,来讨论数据步。

DATA 数据集;

MERGE 数据集1 数据集2 数据集3 ...数据集n;

BY 共同变量1 共同变量2.....共同变量n;

RUN;

注意:数据集必须按照共同变量排序,且所有输入数据集中共同变量的名称、类型和长度必须相同。

让来看一些不同数据集关系下的场景。

一对一关系场景1:在下面的输入数据集中,可以看到这两个表之间基于学生ID存在一对一的关系。现在想要创建一个包含所有独特学生ID及其相应的数学和物理成绩的数据集MARKS。如果学生ID在数学表中不可用,则数学成绩应为缺失值,反之亦然。

使用数据步的解决方案:SAS会比较这两个数据集,并为所有独特的变量创建一个PDV(程序数据向量),并用缺失值初始化它们(程序数据向量是输入和输出数据集之间的中间产物)。在当前示例中,它会创建一个如下的PDV:从输入数据集中读取第一条观察记录,并比较两个数据集中的BY变量值:如果值相等,则将其与PDV中的BY变量值进行比较。如果不相等,则PDV变量会用缺失值重新初始化,并将当前观察记录的值复制到PDV,而其他观察记录保持缺失。如果相等,则PDV变量不会被重新初始化。当前观察记录的可用值会在PDV中更新。之后,记录指针会移动到两个数据集中的下一条观察记录,而在执行RUN语句时,PDV值会被转移到输出数据集中。如果BY变量值不匹配,则具有最低值的数据集的观察记录会被复制到PDV。具有较低BY变量值的数据集的记录指针会移动到下一条观察记录,然后重复步骤2(a)。上述步骤会一直重复,直到两个数据集都到达文件末尾(EOF)。可以进行一次试运行来评估结果数据集。

场景2:基于场景1的输入数据集,想要创建以下输出数据集。

使用数据步的解决方案:让编写与场景1类似的代码,并使用IN选项。

在上面,使用了IN选项与两个输入数据集,并将其值分配给临时变量MATH和PHYS,因为这些是临时变量,所以不能在输出数据集中看到它们。已经展示了具有所有观察记录的变量值的表(PDV数据)以及临时变量。现在,基于这些变量值,可以编写代码进行子集和JOIN操作,以满足需求:如果MATH和PHYS都有值1,则将创建第一个输出数据集,并称为INNER JOIN。如果MATH有1,则将创建第二个输出数据集,并称为LEFT JOIN。如果PHYS有1,则将创建第三个输出数据集,并称为RIGHT JOIN。如果MATH和PHYS中任何一个有1,则将像FULL JOIN一样工作,这在场景1中也已经解决。

一对多关系场景3:这里有两个数据集,学生和考试,想要创建一个输出数据集成绩。

从上面的输入数据集中,可以看到学生和考试之间存在一对多的关系。现在,如果想创建一个输出数据集成绩,其中包含属于STUDENT数据集的每个学生的每次考试的个别观察记录,即左连接。

使用数据步的解决方案:以类似的方式,可以为一对多关系执行内部、右连接和全连接操作,使用IN操作符。

多对多关系场景4:创建一个基于共同字段的所有组合的输出数据集。也可以看到两个输入数据集都存在多对多的关系。

数据步不执行多对多关系,因为它不提供输出作为笛卡尔积。当使用数据步合并表A和表B时,输出类似于下面的快照。

已经看到,如何使用数据步合并两个或多个数据集,除了多对多关系之外的任何关系。现在来看PROC SQL方法来解决类似的要求。

PROC SQL:要理解SQL中的连接方法,首先需要理解笛卡尔积。笛卡尔积是一个在FROM子句中有多个表的查询,它产生输入表的所有可能的行组合。如果有两个分别有2和4条记录的表,那么使用笛卡尔积,将有一个有2 X 4=8条记录的表。

SQL连接适用于数据集之间的每种关系(一对一、一对多和多对多)。让看看它如何与不同类型的连接一起工作。

SELECT 列-1, 列-2,…列-n FROM 表1 INNER/LEFT/RIGHT/FULL JOIN 表2 ON 连接条件 <其他子句>;

注意:表可能或可能不需要在共同变量上排序。共同变量的名称可能不相似,但必须具有相似的长度和类型。最多可以与两个表一起工作。

让使用PROC SQL解决上述要求。

场景1:这是一个FULL JOIN的例子,需要在输出数据集中包含所有学生ID及其相应的数学和物理成绩。

在上面的输出数据集中,可以看到,那些只参加了物理考试的学生的学生ID缺失了。为了解决这个问题,将使用一个函数COALESCE。它返回给定变量中第一个非缺失参数的值。

COALESCE (参数-1, 参数-2,…..参数-n)

让修改上述代码:

场景2:这是一个INNER、LEFT和RIGHT JOIN的例子。这里解决内部连接的问题。

同样,可以为左连接和右连接做同样的事情。

场景3:这是一个一对多关系的左连接问题。

场景4:这是一个多对多关系的问题。已经讨论过SQL可以产生包含两个表之间所有记录组合的笛卡尔积。

已经看过了Proc SQL来连接/合并数据集。

结束语:在本系列关于SAS中合并数据集的文章中,看了各种合并数据集的方法,比如追加、连接、交错和合并。特别是在本文中,讨论了根据数据集之间的关系,各种类型的连接以及如何根据不同场景解决它们。使用了两种方法(数据步和PROC SQL)来实现结果。将在将来的文章中查看这些方法的效率。

觉得这个系列有用吗?已经简化了像合并数据集这样的复杂主题,并试图以易于理解的方式呈现。如果需要更多关于合并数据集的帮助,请随时在下面的评论中提出问题。

  • 在SAS中选择变量并将它们转移到新数据集
  • 将Excel的前20条记录导入到SAS
  • SAS中的WHERE语句不起作用
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485