列号更改时使用sas查找表

时间:2016-09-07 14:31:04

标签: sas sas-iml

我有两个sas数据集,

Table 1                        Table 2
col1 col2 col3 col4 col5       a  b
.    1    2    3    4          1  1          
1    5    8    6    1          1  4
2    5    9    7    1          4  3
3    6    9    7    1          2  1
4    6    9    7    2          2  2

其中表1是表2中值a和b的查找表,这样我就可以创建列c。在表1中,a等于col1,b对应于row1(即表2中的新列c应为5,1,7,5,9。如何在sas中实现此目的。我正在考虑将表1读入2d数组然后得到列c =数组(a,b),但不能让它工作

3 个答案:

答案 0 :(得分:1)

这是一个IML解决方案,首先,因为我认为这对您来说真的是“最佳”解决方案 - 您正在使用矩阵,因此请使用矩阵语言。我不确定是否存在非循环方法 - 可能存在;如果你想知道,我会在问题中添加标签,看看Rick Wicklin是否出现在这个问题上。

data table1;  
input col1 col2 col3 col4 col5      ;
datalines;
.    1    2    3    4           
1    5    8    6    1         
2    5    9    7    1         
3    6    9    7    1         
4    6    9    7    2    
;;;;
run;

data table2;
input a  b;
datalines;
 1  1        
 1  4
 4  3
 2  1
 2  2
;;;;
run;

proc iml;
use table1;
read all var _ALL_ into table1[colname=varnames1];
use table2;
read all var _ALL_ into table2[colname=varnames2];

print table1;
print table2;

table3 = j(nrow(table2),3);
table3[,1:2] = table2;

do _i = 1 to nrow(table3);
  table3[_i,3] =  table1[table3[_i,1]+1,table3[_i,2]+1];
end;
print table3;
quit;

答案 1 :(得分:0)

这是临时阵列解决方案。它并不是那么漂亮。如果速度是一个问题,你不必循环遍历阵列插入它,你可以使用直接内存访问,但我不想这样做,除非速度是一个巨大的问题(如果它是,您应该首先使用更好的数据结构。

data table3;
  set table2;
  array _table1[4,4] _temporary_;
  if _n_ = 1 then do;
    do _i = 1 by 1 until (eof);
      set table1(firstobs=2) nobs=_nrows end=eof;
      array _cols col2-col5;
      do _j = 1 to dim(_cols);
        _table1[_i,_j] = _cols[_j];
      end;
    end;
  end;
  c = _table1[a,b];
  keep a b c;
run;

答案 2 :(得分:0)

只需在SET语句中使用POINT =选项来选择行。然后,您可以使用ARRAY选择列。

data table1 ;
  input col1-col4 ;
cards;
5    8    6    1         
5    9    7    1         
6    9    7    1         
6    9    7    2    
;
data table2 ;
 input a b ;
cards;
 1  1   
 1  4
 4  3
 2  1
 2  2
;

data want ;
  set table2 ;
  p=a ;
  set table1 point=p ;
  array col col1-col4 ;
  c=col(b);
  drop col1-col4;
run;