SAS-根据更多变量的所有可能组合查找并分配ID

时间:2019-02-22 10:59:57

标签: sas combinations scanning id

我需要为三个变量中的每个相同值的组合分配相同的ID,但我真的不知道该怎么做才能在三个变量中发现相同的三个字母的组合(A-B-C应该与B-C-A匹配) 这是我的输入数据:

data HAVE;
input ID VAR1 VAR2 VAR3 $;
DATALINES;
001 A B C
002 A C B
003 B C A
004 A B 
005 B A 
006 D E F
007 E F D
008 F E D
009 E F 
010 F E
;
RUN;

结果ID_NEW应为:

data HAVE;
input ID VAR1 VAR2 VAR3 $ ID_NEW;
DATALINES;
001 A B C 1
002 A C B 1
003 B C A 1
004 A B   2
005 B A   2
006 D E F 3
007 E F D 3
008 F E D 3
009 E F   4
010 F E   4
;
RUN;

我能够通过proc sql识别两个的组合,并使用键t1.var1 = t2.var2和t1.var2 = t2.var1执行左联接,但是它可以识别三个字母组合,我想避免加入联接,因为我可以有6种可能的组合,而且我觉得有一个聪明的方法,无需重复联接6次!也许结合了catt和扫描功能?

在此先感谢您的帮助:)!

2 个答案:

答案 0 :(得分:1)

ID_NEW基于组合。每个独特的组合都可以视为一个设置元素。通过对数据值进行排序(将值排列转换为代表值组合的不同排列)并将其与定界符串联为一个单个值(即集合元素),可以得出set元素。定界确保元素中贡献值的分离。 set元素也可以被视为哈希键,并且提供了单遍解决方案。

示例

perm     sort     element/key
A B C -> A B C -> A,B,C
B C A -> A B C -> A,B,C

CALL SORTC将对变量进行排序,但是您不想对实际变量进行排序,因此必须将值复制到其他要排序的变量中(并从输出中删除)

hash可以将键值与combination_id关联。每次遇到新的键值时,combo_id都会增加,或者在键已存在时会重新获取。

示例:

data HAVE;
input ID VAR1 $ VAR2 $ VAR3 $;
DATALINES;
001 A B C
002 A C B
003 B C A
004 A B .
005 B A .
006 D E F
007 E F D
008 F E D
009 E F .
010 F E .
011 C A B
012 E D F
RUN;

data want;
  if 0 then set have; * prep pdv;

  length _key $100 combo_id 8; * host variables for hash;

  if _n_ = 1 then do;
     declare hash ids();
     ids.defineKey ('_key');
     ids.defineData ('combo_id');
     ids.defineDone();
  end;

  set have;

  * copy data into variables that will be sorted;

  * combination of raw data;
  * use cats in case some of variables are numeric;
  _item1 = cats(var1);
  _item2 = cats(var2);
  _item3 = cats(var3);

  * alternative if combo_id is to be based on formatted data values;
  * use vvalue to obtained formatted representation of data values;
  * _item1 = vvalue(var1);
  * _item2 = vvalue(var2);
  * _item3 = vvalue(var3);

  array items _item1-_item3;  * arrayify the _items so they can be sorted;

  call sortc(of items(*));

  * delimit with hex 255, a character not likely to occur
  * in the data value or formatted representation;

  _key = catx('FF'x, of items(*)); 

  * retrieve or increment the combo_id;

  if ids.find() ne 0 then do;
    combo_id = ids.num_items + 1;
    ids.add();
  end;

  drop _:;
run;

答案 1 :(得分:0)

您将可以使用SORTC函数执行此操作,该函数将字符值数组按字母顺序排序:

http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003106052.htm

一种方法是创建一个新变量,该变量包含按字母顺序排列的VAR1-VAR3的值:

data want;
  length sorted_vars $ 20;
  set have;
  array vars[*] var1-var3;
  call sortc(of vars[*]);
  sorted_vars = cats(of vars[*]);
run;

上面的代码尚未经过测试,但应该非常接近。从那里,您可以对sorted_vars进行排序,并在每个id_new上增加first.sorted_vars变量。