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;
我有以下格式的数据,
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;