如何选择每个分支总共 3 个 obs?

how to choose total of 3 obs per branch?

我希望每个分支只选择 3 个 OBS,我需要回答这些规则:

  1. 如果分支机构中只有 2 个账户 - 从第一个分支机构获取 2 个最高收入,从第二个账户获取 1 个收入
  2. 如果分支中有 3 个账户 - 每个账户带 1 个观察值,即最高的。
  3. 如果每个分支机构有 4 个或更多帐户 - 每个帐户带 1 个观察值,这是最高的 - 同时不重复同一帐户两次

嗯。 . . row_id 列似乎在对帐户内的收入进行排序。所以,你应该可以使用proc sql,虽然有点乱:

select t.*
from t join
     (select crm_branch_id, count(distinct account_id) as cnt
      from t
      group by crm_branch_id
     ) b
     on b.crm_branch_id = t.crm_branch_id
where (cnt = 1 and t.row_id <= 3) or
      (cnt = 2 and t.row_id = 1 or
       cnt = 2 and t.row_id = 2 and
       t.income = (select max(t2.income)
                 from t t2
                 where t2.crm_branch_id = t.crm_branch_id and
                       t2.row_id = 2
                )
      ) or
      (cnt = 3 and row_id = 1) or
      (cnt > 3 and row_id = 1 and
       (select count(*)
        from t t2
        where t2.crm_branch_id = t.crm_branch_id and
              t2.row_id = 1 and
              t2.income >= t.income
       ) <= 3
      );

where 子句中的神秘逻辑是处理不同数量的帐户:

  • 如果只有一个帐号,取前三行。
  • 如果有两个帐户,取 row_id = 1 的两行,然后是 row_id = 2.
  • 的第一行
  • 如果有三个账户,取row_id = 1行。
  • 如果有四个或更多帐户,则只考虑 row_id = 1 所在的行。然后根据收入取前三。

DOW处理可以进行肤色选择

  • 第一个循环,计算branch
  • 中的account个数
  • 第二次循环,按照规则输出topincomes
    • 需要按以下方式预先订购数据
      • branchaccount
      • 中连续
      • 降序income
      • 升序seq_act

示例:

data have;
input income account_id branch_id seq_act;
datalines;
 1224932 123 358 1
  700400 123 358 2
  646730 123 358 3
  644677 123 358 4
    2017 123 358 5
11338320 567 358 1
 3806060 567 358 2
 3642089 567 358 3
 1403174 567 358 4
  400530 567 358 5
;

/* presume data is
 * - contiguous by branch and account
 * - descending income
 * - ascending seq_act
 */

data want(drop=i n);
  * count number of accounts in branch;
  do until (last.branch_id);
    set have;
    by branch_id account_id notsorted descending income /*ascending*/ seq_act;

    n + first.account_id;
  end;

  do until (last.branch_id);

    set have;
    by branch_id account_id notsorted;

    i + first.account_id;

    select (n);
      when (1) if seq_act <= 3 then output;   /* first 3 when 1 account */
      when (2) if seq_act <= 3-i then output; /* first 2 then first 1 when 2 accounts */
      otherwise if seq_act = 1 then output;   /* first 1 from each account */
    end;
  end;

  i = 0;
  n = 0;
run;

输出