【问题标题】:Combination of grouped values in SASSAS中分组值的组合
【发布时间】:2021-04-12 19:48:06
【问题描述】:

我仅在以下数据集中的记录仅因列类型而异的情况下才尝试查找各种​​组合。例如:前三行仅因列类型不同而不同

给定数据集

ins_id    ins_number   type
1234      1234-1234-1  AU
1234      1234-1234-1  HM
1234      1234-1234-1  RE
567       567-567-12   TL
567       567-567-13   TL
9101      9101-1234-1  AU
9101      9101-1234-1  TX
9101      9101-1234-1  CN
8854      8854-1234-1  TX
8854      8854-1234-1  GB
8854      8854-1234-1  RE
8854      8854-1234-2  RX

Expected Output:
combination  count
AU,HM,RE     1
AU,TX,CN     1
TX,GB,RE     1

我尝试编写查询,但没有得到所需的输出,请帮助:

proc sql;create table tst as select cp.type, 
       count(distinct ins_id)
from (select distinct fac_prod_typ from dataset3a) cp cross join
     (select distinct ins_number from dataset3a) pes left join
     dataset3a
     on dataset3a.type = cp.type and
        dataset3a.ins_number = pes.ins_number
group by cp.type, pes.ins_number;quit;

【问题讨论】:

  • 使用 BY 组处理,这里的数据步骤会容易得多。这是一个选项吗?
  • 可以,只要输出正确即可。
  • 如果在一个组内的不同类型中存在重复类型,您希望该类型出现多少次? (例如一个有6条记录、3种类型和一些重复的id可以总结为AU,HM(3),RE(2)

标签: sas proc-sql


【解决方案1】:

您需要对数据进行排序以确保类型列表在所有 id 上都是一致的。 SET...; BY...; 上的 DOW 循环将为每组输出一个类型列表。 最后一步是使用 Proc FREQ 计算每个类型列表的 id 数。

例子:

data have;
informat ins_id $8. ins_number $25. type $2.;
input ins_id  $  ins_number $  type $;
cards;
1234      1234-1234-1  AU
1234      1234-1234-1  HM
1234      1234-1234-1  RE
567       567-567-12   TL
567       567-567-13   TL
9101      9101-1234-1  AU
9101      9101-1234-1  TX
9101      9101-1234-1  CN
8854      8854-1234-1  TX
8854      8854-1234-1  GB
8854      8854-1234-1  RE
8854      8854-1234-2  RX
;

/* force specific ordering of type within group id and number */
/* necessary for proper frequency counting */
/* if sequence of types IS important do not sort and data step by ... NOTSORTED */

proc sort data=have;
  by ins_id ins_number type;
run;

data types(keep=types);
  length types $200;
  do until (last.ins_number);
    set have;
    by ins_id ins_number;
    if indexw(types, type) = 0 then types = catx(',',types,type);
  end;
  if index(types,',') then output;
run;

proc freq noprint data=types;
  table types / out=types_counts(keep=types count) ;
run;

【讨论】:

  • 嗨,Richard,如果我们像我在原始帖子中所做的那样再添加一行,它将不起作用。那个测试用例失败了。所以基本上,对于 8854,应该有 TX、GB、RE 而不是 RX
  • 我明白了。 BY 组需要是两个变量 INS_ID INS_NUMBER。会修复的。
  • 是的,这行得通。你太棒了,谢谢
【解决方案2】:

在这里使用 FIRST/LAST 逻辑很好。 要获得计数,请在最终输出上运行 PROC FREQ,这也可以让您识别混音的 ins_id。

data have;
informat ins_id $8. ins_number $25. type $2.;
input ins_id  $  ins_number $  type $;
cards;
1234      1234-1234-1  AU
1234      1234-1234-1  HM
1234      1234-1234-1  RE
567       567-567-12   TL
567       567-567-13   TL
9101      9101-1234-1  AU
9101      9101-1234-1  TX
9101      9101-1234-1  CN
8854      8854-1234-1  TX
8854      8854-1234-1  GB
8854      8854-1234-1  RE
;;;;

data want;
set have;
by ins_id ins_number type notsorted;
retain combo;
length combo $256.;
if first.ins_number then call missing(combo);

if first.type then combo = catx(", ", combo, type);

if last.ins_number and countw(combo)>1 then output;

run;

【讨论】:

  • 嗨 Reeza,如果我们像我在原始帖子中所做的那样再添加一行,它就不起作用了。那个测试用例失败了。所以基本上,对于 8854,应该有 TX、GB、RE 而不是 RX
  • 所以你只想要前三个?是按订单还是 RX 因其他原因被排除在外?
  • 假设 INS_NUMBER 是关键,只需更改您的 FIRST/LAST 以引用唯一标识分组的最后一个变量。
猜你喜欢
  • 2022-07-13
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
相关资源
最近更新 更多