假设我有一个包含n
行和p
列的数据集,这样数据集中的每个条目都包含一个实数。我正在寻找一种方法来对每行中的p
列进行排名。此排名的输出应该是一个长度 - p
排名的矢量,用于说明关系。
所以,假设我的数据集有5列。第一行可能是row 1 = {10, 13, 3, 3, -4}
。我想在这一行上执行一些操作,最后得到结果row 1 ranks = {3, 4, 2, 2, 1}
。第二行可能类似row 2 = {8, 3, -6, 5, 2}
,此行的结果应为row 2 ranks = {5, 3, 1, 4, 2}
。
这项功能是否在SAS中实施?我已经生成了不考虑关系的代码,但是它们经常发生,以至于需要花费不合理的时间来纠正错误地进行的行排名。
答案 0 :(得分:5)
有趣的问题;这是一个可能的解决方案:
data have;
p1=10; p2=13; p3=3; p4=3; p5=-4; output;
p1=8; p2=3; p3=-6; p4=5; p5=2; output;
run;
data want;
set have;
array p(*) p1-p5;
array c(*) c1-c5;
array r(*) r1-r5;
/* Copy vector to temp array and sort */
do i=1 to dim(p);
c(i) = p(i);
end;
call sortn(of c(*));
/* Search new sorted array for the original position */
do i=1 to dim(c);
if i = 1 then rank=1;
else if c(i) ne c(i-1) then rank + 1;
do j=1 to dim(p);
if p(j) = c(i) then do;
r(j) = rank;
end;
end;
end;
/* PUT statement to see result in log */
put +3 p(*)
/ +3 c(*)
/ +3 r(*);
drop i j rank c1-c5;
run;
答案 1 :(得分:3)
听起来像你需要几个阵列才能做到这一点。
我现在没有时间编写代码,但是使用像这样的东西会做很多繁重的工作:
答案 2 :(得分:2)
即使OP说他不使用IML以防其他人发现这个有用的搜索,也可以添加它。 IML实际上是解决这个问题最简单的方法,因为它基本上是一个向量/矩阵问题......
proc iml;
p={10 13 3 3 -4, 5 6 5 2 3};
r=j(2,5,.);
print p r;
do i = 1 to nrow(p);
r[i,]=ranktie(p[i,]);
end;
print p r;
quit;
它确实对待尝试与OP略有不同,因此需要一些工作来使其完全像所要求的解决方案 - 但一般来说,1,2.5,2.5,4,5 [或1,2,2,4] ,5]可能是你真正想要的,而不是1,2,2,3,4。 4和5应保持4和5,不要移动到3和4,当2和3平局时。
答案 3 :(得分:2)
只是为了好玩,考虑到OP想要一个带有排名的新数据集的答案,这里是PROC RANK方法。可能不比数据步骤快,但可能更简单,更容易在多种情况下使用,并且具有额外的优势,即您不能在编码中真正犯错(没有它实际崩溃)。
data have;
input id x1-x5;
datalines;
1 10 13 3 3 -4
2 5 6 5 2 3
;;;;
run;
proc transpose data=have out=temp;
by id;
var x1-x5;
run;
proc rank data=temp out=temprank;
var col1;
by id;
run;
proc transpose data=temprank out=want(drop=_name_ _label_);
by id;
var col1;
id _name_;
run;