4

假设我有一个包含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 中实现?我生成的代码不考虑平局,但它们经常发生,以至于纠正错误完成的行排名需要不合理的时间。

4

4 回答 4

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;
于 2013-01-07T19:53:28.297 回答
3

在我看来,您需要几个数组才能做到这一点。

  1. 数组 1:存储排名的数组
  2. 数组 2:对值进行排序的数组
  3. 数组 3:原始未更改的数据

我现在没有时间编写代码,但是使用这样的东西会做很多繁重的工作:

http://support.sas.com/kb/24/754.html

于 2013-01-07T19:47:11.533 回答
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 并列时。

于 2013-01-07T20:20:38.217 回答
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;
于 2013-01-07T21:31:51.570 回答