如何在SAS/SQL中横向合并无匹配数据集生成笛卡尔积?
生成SAS数据集全组合(笛卡尔积)的解决方案
嗨,我来帮你搞定这个SAS生成全组合数据集的需求!你要的其实就是两个数据集的笛卡尔积(所有可能的配对组合),55条Code记录×167条Persons记录正好是9185条,下面给你两种最实用的实现方法:
方法一:用PROC SQL快速实现(最推荐)
PROC SQL在没有关联条件的情况下,会自动生成两个表的全组合,代码超简洁,完全满足你的需求:
proc sql; create table Full_Combination as select p.Person_id, c.Code_value from Persons p, Code c; /* 没有WHERE子句,直接生成笛卡尔积 */ quit;
说明:
- 这里不需要任何匹配条件,SQL引擎会自动把每个
Person_id和所有Code_value配对 - 生成的数据集
Full_Combination会包含Person_id和Code_value两个变量,正好9185条观测 - 如果你的变量名有重复(这里你说两个数据集变量分别是
Code_value和Person_id,所以没问题),可以用别名区分
方法二:用DATA步实现(适合需要额外逻辑的场景)
如果你已经尝试过DATA步,可能之前的思路没走对,下面是用数组+RETAIN的方式实现的版本:
/* 第一步:先获取Code数据集的总观测数,存成宏变量 */ proc sql noprint; select count(*) into :code_count from Code; quit; /* 第二步:用DATA步生成全组合 */ data Full_Combination; /* 定义数组存储所有Code_value,注意如果是数值型变量就去掉$ */ array codes[&code_count] $ /* 这里可以指定长度,比如$20,根据你的Code_value实际长度调整 */; retain codes:; /* 保留数组的值,不会每次循环重置 */ /* 第一次循环时,把Code的所有Code_value存入数组 */ if _n_ = 1 then do i = 1 to &code_count; set Code; codes[i] = Code_value; end; /* 读取Persons的每条记录,循环数组输出所有配对 */ set Persons; do i = 1 to &code_count; Code_value = codes[i]; output; /* 输出当前Person_id和对应的Code_value */ end; /* 清理临时变量 */ drop i codes:; run;
说明:
- 先把Code的所有值预存到数组里,避免反复读取数据集
- 对每个
Person_id,遍历数组输出所有Code_value的配对 - 如果后续需要给组合添加额外计算(比如标记某些组合),这种方法更容易扩展
两种方法都能生成你需要的结果,个人更推荐PROC SQL,代码更简洁易维护。如果有变量类型适配问题(比如Code_value是数值型),调整数组定义即可。
内容的提问来源于stack exchange,提问作者user1626092
相关产品推荐
相关产品推荐

