【问题标题】:SAS combining datasets, binary search, indicesSAS 结合数据集、二分搜索、索引
【发布时间】:2013-03-08 16:59:51
【问题描述】:

在 SAS 中,对于下面的两个测试数据集 - 对于落在“y”和“z”内的每个“数量”值,我需要提取相应的“x”。可能有多个符合标准的“x”值。 最终结果应如下所示:

/*
4 banana eggs
15 .
31 .
7 banana
22 fig
1 eggs
11 coconut
17 date
41 apple
*/

我意识到这依赖于使用索引或二进制搜索,但我想不出一个可行的解决方案!任何帮助将不胜感激!谢谢!

data test1;
   input x $ y z;
   datalines;
   apple 29 43
   banana 2 7
   coconut 9 13
   date 17 20
   eggs 1 5
   fig 18 26
   ;
run;

data test2;
   input amount;
   datalines;
   4
   15
   31
   7
   22
   1
   11
   17
   41
   ;
run;

【问题讨论】:

    标签: loops dataset sas indices


    【解决方案1】:

    加入两个数据集,使amount 介于yz 之间。

    proc sql;
    create table join as 
    select a.amount
          ,b.*
    from test2 a
           left join
         test1 b
           on a.amount between b.y and b.z;
    quit;
    

    按数量对结果进行转置。

    proc sort data=join; by amount; run;
    

    转置它。

    proc transpose data=join out=trans;
    by amount;
    var x;
    run;
    

    现在您的每个水果都在其自己的变量中,名为 col1col2、...。 如果您想将它们全部放在一个变量中,用空格分隔,只需将它们连接起来即可。

    data trans2(keep= amount text);
    set trans(drop=_name_);
    array v{*} _character_;
    text = catx(' ', of v{*});
    run;
    

    【讨论】:

      【解决方案2】:

      这是使用“老式”数据步骤代码加上PROC TRANSPOSE的可能解决方案:

      data test1;
          input x $ y z;
          datalines;
          apple 29 43
          banana 2 7
          coconut 9 13
          date 17 20
          eggs 1 5
          fig 18 26
      run;
      
      data test2;
          input amount;
          datalines;
          4
          15
          31
          7
          22
          1
          11
          17
          41
      run;
      
      data want(keep=amount x);
         set test2;
         found = 0;
         do _i_=1 to nobs;
            set test1 point=_i_ nobs=nobs;
            if y <= amount <= z then do;
               found = 1;
               output;
               end;
            end;
         if not found then do;
            x = ' ';
            output;
            end;
      run;
      
      proc transpose data=want out=want2(drop=_name_);
         by amount notsorted;
         var x;
      run;
      

      请注意,我的结果与您的示例不匹配;数量 31 是一个“苹果”。

      【讨论】:

      • 非常感谢!这和上面的解决方案一样有效!你是对的,金额 31 是一个“苹果”——这是我的错误!
      猜你喜欢
      • 1970-01-01
      • 2014-04-14
      • 2015-07-12
      • 1970-01-01
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      相关资源
      最近更新 更多