对大数据进行 SAS 左连接以及选择条件中使用的 case 语句的省时方法

问题描述 投票:0回答:1

我有 2 个 .sas7bdat 格式的数据,我需要根据某些条件对它们执行左连接。 PROC SQL 的概述如下:

PROC SQL;
  CREATE TABLE XYZ 
     SELECT T1.A,
     case statement
       case
           when max(T1.X) <= 0 then T1.X           
           when max(T1.X) > 0 then T2.Y
           AS FINAL_XY
     FROM T1 left join T2 ON
     T1.A= T2.A
     T1.B=T2.B AND
     UPCASE(T1.C)="CLASS1"
    quit;

两个 SAS 数据集均约为 2GB。任何有效的方法我都可以完成这件事。上述语句需要近一个小时才能完成并生成输出。 如果可以提供比上面更好的性能,我也可以使用数据步骤操作。 如果这是一个问题,我没有内存限制: 内存:64 GB。以防万一,这些信息很有帮助。

编辑:执行 SAS SQL 语句,在某些情况下,我需要从 table2 或 table1 中分配值。因此,本质上是尝试连接两个表并创建一个新表,其中包含 table1 中的一些列,而 table2 中的一些列基于 case 语句中指定的条件。

performance sas left-join proc
1个回答
0
投票

确保数据集按关键变量排序,然后合并它们。 如果第二个数据集中有未出现在第一个数据集中且想要忽略的键组合,您可以使用 IN= 数据集选项创建标志变量来指示数据集是否对观察有贡献。

因此,当 A 和 B 唯一标识 T2 中的观测值时,左连接以及 A 和 B 将如下所示:

data XYZ;
  merge T1 (in=in1) T2 ;
  by A B ;
  if in1 ;
run;

假设合并的原因是将 T2 中的 Y 值(而不是 T2 中的其他变量)附加到 T1 的观察结果,那么 MERGE 语句可能如下所示:

merge T1(in=in1) T2(keep=A B Y);

为了模拟在连接条件中包含变量 C 的额外测试的影响,您可以添加一个 IF 语句,当条件不成立时清除新变量。

 if not (UPCASE(T1.C)="CLASS1") then call missing(Y);

要添加尚未来自 T1 或 T2 的其他变量,您可以使用普通的编程语言语句,例如赋值语句和 IF/THEN 逻辑(而不是 SQL 的复杂 CASE 语法)。

但是,如果您确实需要生成聚合统计信息,例如示例中的 MAX(),那么可能需要更多时间,因为您至少需要第二次遍历数据来计算这些统计信息。 (SQL 代码也需要额外的传递,但它会为您完成。)因此,对于您的示例,您实际上只需要首先找到 X 的最大值。例如,您可以使用 PROC SUMMARY 来做到这一点,然后将该值包含到您生成的数据集,以便您可以在代码中引用它。

proc summary data=t1 ;
  var X;
  output out=max_x max=max_x ;
run;
data XYZ;
  if _n_=1 then set max_x(keep=max_x);
  merge T1 (in=in1) T2 (keep=A B Y) ;
  by A B ;
  if in1 ;
  if not (UPCASE(T1.C)="CLASS1") then call missing(Y);
  if max_x <= 0 then FINAL_XY = X;
  else FINAL_XY=Y;         
run;

但是,由于分配给 FINAL_XY 的值的逻辑似乎并不依赖于当前观察中任何实际变量的值,因此您可能只使用宏代码来有条件地生成两个赋值语句中的任何一个。

© www.soinside.com 2019 - 2024. All rights reserved.