【问题标题】:SAS: merge/ join datasets by dynamic columns in the look up tableSAS:通过查找表中的动态列合并/连接数据集
【发布时间】:2018-04-13 02:19:42
【问题描述】:

我想将 sas 数据集与查找表连接,但用于连接的列/键是查找表中的值

数据集:table4

             ID  lev1   lev2   lev3   lev4  lev5
              1  12548  14589  85652  45896 45889
              2  12548  14589  85652  45896 45890
              3  12548  14547  85685  45845 45825
              4  66588  24647  55255  30895 15764

查表:

           context   table_name column operator value
            extract   table1     col1  equals  xyd
            asset     table2     var1  equals  11111
            asset     table2     var2  equals  25858
            prod      table3     x1    equals  87999
            unprod    table4     lev2  equals  14589
            unprod    table4     lev2  equals  14589
            unprod    table4     lev3  equals  55255

现在我想将 table4 与查找表连接,但只能使用字段 lev2 和 lev3(它是动态的,因此将来可能会更改,所以不想在其中进行硬编码)。

我尝试过下面的代码,但不想硬编码,因为字段是动态的(将来有人可能还会添加 lev4)。

proc sql ;
create table want as 
select ID
from  table4 as a 
inner join  lookup as b 
on  a.lev2 = input(value,12.) or a.lev3=input(value,12.)
where Context="unprod";
quit;

提前致谢。

【问题讨论】:

  • 您能否转置第一个表,以便只有一列用于连接?这样就可以完全避免这个问题?
  • 感谢您的回复。不幸的是,每个级别都有 1000 个值,并且大约有 20 个级别。上面的表格只是解释我想要实现的目标的示例。
  • 这使得转置数据的情况更强大,不是吗。这样,无论有多少列或多少级别,解决方案都将是完全动态的......
  • 发布您期望的输出,并将您的数据作为数据步骤发布,我将模拟解决方案。如果您不知道如何包含数据步骤说明,请参见此处:communities.sas.com/t5/SAS-Communities-Library/…
  • 那不是查找表。这是一套规则。你想对规则做什么?

标签: sas proc-sql


【解决方案1】:

这看起来不像查找表。它似乎是一组规则。您可以使用它来生成代码。让我们通过使表包含实际代码而不是三列来简化过程。但是您可以轻松编写代码以将当前格式转换为代码字符串。

data rules ;
  infile cards truncover ;
  input context $ table_name $  rule $100. ;
cards;
extract   table1     col1  =  xyd
asset     table2     var1  =  11111
asset     table2     var2  =  25858
prod      table3     x1    =  87999
unprod    table4     lev2  =  14589
unprod    table4     lev2  =  14589
unprod    table4     lev3  =  55255
;

所以现在看起来您想要获取具有特定值CONTEXT 的规则,并使用它从TABLE_NAME 中命名的数据集生成一个新数据集。不确定要为生成的表使用什么名称,或者在同一“上下文”中提到多个表时要做什么。

%let context=unprod ;

filename code temp;
data _null_;
  set rules ;
  where context=symget('context');
  by table_name ;
  file code ;
  if first.table_name then table_no+1;
  if first.table_name then put
  'data want' table_no ';'
/ '  set ' table_name ';'
/ '  where 1=0'
  ;
  put '  or (' rule ')' ;
  if last.table_name then put
  ';'
/ 'run;'
  ;
run;

%include code / source2 ;

这会产生如下代码:

130  +data want1 ;
131  +  set table4 ;
132  +  where 1=0
133  +  or (lev2  =  14589 )
134  +  or (lev2  =  14589 )
135  +  or (lev3  =  55255 )
136  +;
137  +run;

NOTE: There were 3 observations read from the data set WORK.TABLE4.
      WHERE (lev2=14589) or (lev3=55255);
NOTE: The data set WORK.WANT1 has 3 observations and 6 variables.

【讨论】:

    【解决方案2】:

    这是一个示例代码,可以理解您正在尝试做的事情。此代码基于@Reeza 的评论。如果这不是您想要做的,请发送一个示例输出文件。

    data table4;
    input              ID $ lev1 $  lev2 $  lev3 $  lev4 $ lev5 $;
    datalines;
                  1  12548  14589  85652  45896 45889
                  2  12548  14589  85652  45896 45890
                  3  12548  14547  85685  45845 45825
                  4  66588  24647  55255  30895 15764
    ;
    run;
    
    data look_up;
    input context $  table_name $ column $ operator $ value $;
    datalines;
                extract   table1     col1  equals  xyd
                asset     table2     var1  equals  11111
                asset     table2     var2  equals  25858
                prod      table3     x1    equals  87999
                unprod    table4     lev2  equals  14589
                unprod    table4     lev2  equals  14589
                unprod    table4     lev3  equals  55255
    ;
    run;
    
    
    
    PROC transpose DATA=work.table4 out=temp1  prefix=value;
        by ID;
        VAR lev1-lev5;
    run;
    
    proc sql;
        create table want as 
        select a.*, b.ID 
        from look_up as a 
        inner join temp1 as b 
        on a.value=b.value1 and a.column=_Name_;
    quit;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 2019-02-16
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      相关资源
      最近更新 更多