【问题标题】:How to reverse a column in SAS by an specific ID?如何通过特定 ID 反转 SAS 中的列?
【发布时间】:2019-11-09 15:58:33
【问题描述】:

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

+----+------------+-------+
| 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 的顺序不应更改。

【问题讨论】:

  • 堆栈溢出不是代码编写服务。显示您尝试过的内容以及遇到的错误。一种方法是使用两个分组 DOW 循环,第一个将散列加载为 LIFO 堆栈,第二个卸载 LIFO 堆栈。另一种是假定最大组大小并使用临时数组作为 LIFO 堆栈。
  • 为什么 ID=3 的 ID_COUNT 不遵循其他值的模式?为什么不直接删除 ID_COUNT 并重新创建它?
  • ID_Count是一个变量,用于数据集的其他变量,所以不能排除。它遵循的规则是,当 ID 重复时,它得到形状“-”,当它不重复时,它得到“”。
  • 如果您知道规则,您可以重新创建它。我很好奇当重复次数超过 9 次时这种格式是如何工作的。

标签: sorting sas dataset proc-sql


【解决方案1】:

可能有一种更直接的方法可以做到这一点,但以下应该可行:

第 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;

第三步合并数据:

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;   

【讨论】:

  • 感谢您的回答。您提出的如何处理问题的想法解决了问题。我简化了你给的一些代码,真的很好用。
【解决方案2】:

将临时数组作为堆栈是一种简单的方法。当组的行数多于临时数组的插槽数时,输出将停止并出现错误。在此示例中,有 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;

【讨论】:

    猜你喜欢
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 2022-11-30
    • 1970-01-01
    相关资源
    最近更新 更多