SAS 9.3:更改缺少行的矩阵的形状

SAS 9.3: Changing the shape of matrix with missing rows

我有以下格式的数据,

P1 P2 Score  
A  A  1  
A  B  2  
A  C  5  
B  B  4   
B  C  9  
C  A  3  
C  B  6  

我想把它们变成一个 3*3 矩阵,因为那些缺失的行是零。

我用谷歌搜索并找到了这个
http://blogs.sas.com/content/iml/2012/01/16/reading-all-variables-into-a-matrix.html
但我不知道我是否缺少行,我该怎么做?

如果您想创建一个代表 3x3 矩阵的 SAS 数据集,您可以使用 PROC TRANSPOSE 从您的数据中做到这一点。可以通过多种方式填充 P1 和 P2 的缺失组合。您的数据适合使用 PROC SUMMARY COMPLETETYPES 的功能来填充零。

data p;
   input (P1 P2)(:.) Score;
   cards;
A A 1
A B 2
A C 5
B B 4
B C 9
C A 3
C B 6 
;;;;
   run;
proc summary data=p completetypes nway;
   class p:;
   freq score;
   output out=filled(drop=_type_ rename=(_freq_=Score));
   run;
proc print;
   run;
proc transpose out=M3x3;
   by P1;
   id P2;
   var score;
   run;
proc print;
   run;

我可能也会在 base SAS 中执行此操作,但它在 IML 中也很可行。我用unique-loc方法把你的ABC转成数值,然后用FULL函数对矩阵进行平方:

data have;
input P1 $ P2 $ Score;
datalines;
A  A  1  
A  B  2  
A  C  5  
B  B  4   
B  C  9  
C  A  3  
C  B  6  
;;;;
run;
proc iml;

use have;
read all var _NUM_ into have_mat;
read all var _CHAR_ into p_mat;

p1_unique = unique(p_mat[,1]);  *get unique values of p1;
p2_unique = unique(p_mat[,2]);  *get unique values of p2;

num_mat = j(nrow(p_mat),3,0);   *generate empty matrix to populate;

do i = 1 to ncol(p1_unique);    *code the p1 values;
  idx = loc(p_mat[,1] = p1_unique[i]);
  num_mat[idx,2] = i;           *sparse matrix format requires 2nd col be row values;
end;

do i = 1 to ncol(p2_unique);    *code the p2 values;
  idx = loc(p_mat[,2] = p2_unique[i]);
  num_mat[idx,3] = i;           *sparse matrix format requires 3rd col be col values;
end;

  num_mat[,1] = have_mat;       *and first col is the values for the matrix itself;

final_mat = full(num_mat);      *FULL() function creates a square matrix and fills with 0s;
print final_mat;
quit;

最简单的解决方案是使用 PROC FREQ 中的 SPARSE 选项来构建密集矩阵。然后您可以将数据读入 SAS/IML 并重塑它以使其成为正方形。使用 'p' 作为数据集的名称(与其他答案一样):

proc freq data=p noprint;
tables p1*p2 /sparse out=P2;  /* P2 is dense */
weight score;
run;

proc iml;
use p2;  read all var {Count};  close p2;
x = shape(count, sqrt(nrow(Count)));
print x;