如何通过特定 ID 反转 SAS 中的列?

How to reverse a column in SAS by an specific ID?

我有一个看起来像这样的数据集

+----+------------+-------+
| ID | ID_Count   | Count |
+----+------------+-------+
|  1 |        1.1 |     5 |
|  1 |        1.2 |     4 |
|  1 |        1.3 |     3 |
|  2 |        2.1 |     4 |
|  2 |        2.2 |     2 |
|  3 |          3 |     0 |
|  4 |        4.1 |     5 |
|  4 |        4.2 |     3 |
+----+------------+-------+

我想反转Count列中ID与上一个相同的组,但不反转ID列。我的结果应该是这样的:

+----+------------+-------+
| ID | ID_Count   | Count |
+----+------------+-------+
|  1 |        1.1 |     3 |
|  1 |        1.2 |     4 |
|  1 |        1.3 |     5 |
|  2 |        2.1 |     2 |
|  2 |        2.2 |     4 |
|  3 |          3 |     0 |
|  4 |        4.1 |     3 |
|  4 |        4.2 |     5 |
+----+------------+-------+

ID_Count 只是一列,表示不应更改 ID 的顺序。

可能有更直接的方法来执行此操作,但以下方法应该有效:

第 1 步:将 ROWNO 添加到您的第一个数据集:

data have_row;
retain ROWNO;
set have;
if _n_ = 1 then ROWNO = 0;
ROWNO = ROWNO + 1;
run;

第 2 步创建您要查找的订单并添加 ROWNO:

proc sort data = have out = have_order;
by ID, Count;
run;

data have_order;
retain ROWNO;
set have_order;
if _n_ = 1 then ROWNO = 0;
ROWNO = ROWNO + 1;
run;

第 3 步合并数据:

proc sql noprint;
create want as
select a.id,b.id_count,a.count
from (select * from have_order)as a
left join
select * from have_row as b
on a.rowno=b.rowno;
quit;   

临时数组作为堆栈是一种简单的方法。当组的行多于临时数组的槽时,输出将停止并出现错误。在此示例中,有 10,000 个插槽。

data have;
infile cards dlm='|';
input id id_count count;
datalines;
|  1 |        1.1 |     5 |
|  1 |        1.2 |     4 |
|  1 |        1.3 |     3 |
|  2 |        2.1 |     4 |
|  2 |        2.2 |     2 |
|  3 |          3 |     0 |
|  4 |        4.1 |     5 |
|  4 |        4.2 |     3 |
run;

* serial dows;

data want;
  array stack[10000] _temporary_;
  do _n_ = 1 by 1 until (last.id);
    set have;
    by id;
    stack[_n_] = count;
  end;
  do _n_ = _n_ to 1 by -1;
    set have;
    count = stack[_n_];
    output;
  end;
run;