在列号更改时使用 sas 查找 table
Using a sas lookup table when the column number changes
我有两个 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
其中 table 1 是对 table 2 中的值 a 和 b 的查找 table,这样我就可以创建列 c。在 table 1 中,a 相当于 col1,b 相当于 row1(即 table 2 中的新列 c 应读取 5,1,7,5,9。我如何在 sas 中实现此目的。我正在考虑将 table 1 读入二维数组然后获取列 c = array(a,b),但无法使其工作
首先,这是一个 IML 解决方案,因为我认为这确实是适合您的 'best' 解决方案 - 您正在使用矩阵,因此请使用矩阵语言。我不确定是否有非循环方法——很可能有;如果你想知道,我会在问题中添加 sas-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;
这里是临时数组解决方案。这不是那么漂亮。如果速度是一个问题,你不必遍历数组来插入它,你可以使用直接内存访问,但我不想这样做,除非速度是一个大问题(如果是,你应该使用首先是更好的数据结构)。
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;
只需在 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;
我有两个 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
其中 table 1 是对 table 2 中的值 a 和 b 的查找 table,这样我就可以创建列 c。在 table 1 中,a 相当于 col1,b 相当于 row1(即 table 2 中的新列 c 应读取 5,1,7,5,9。我如何在 sas 中实现此目的。我正在考虑将 table 1 读入二维数组然后获取列 c = array(a,b),但无法使其工作
首先,这是一个 IML 解决方案,因为我认为这确实是适合您的 'best' 解决方案 - 您正在使用矩阵,因此请使用矩阵语言。我不确定是否有非循环方法——很可能有;如果你想知道,我会在问题中添加 sas-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;
这里是临时数组解决方案。这不是那么漂亮。如果速度是一个问题,你不必遍历数组来插入它,你可以使用直接内存访问,但我不想这样做,除非速度是一个大问题(如果是,你应该使用首先是更好的数据结构)。
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;
只需在 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;