我有一个数据集,如下所示:
DATA hogwarts;
INFILE DATALINES delimiter="," dsd;
LENGTH Index Wizards $ 255;
INPUT Index Wizards $ Points;
DATALINES;
1,'Harry Potter Ron Weasley',100
2,'Hermione Granger Harry Potter',200
3,'Ron Weasley',300
;
RUN;
换句话说,它看起来像这样:
索引 | 巫师 | 积分 |
---|---|---|
1 | 哈利·波特罗恩·韦斯莱 | 100 |
2 | 赫敏格兰杰哈利波特 | 200 |
3 | 罗恩·韦斯莱 | 300 |
我需要发现存储在
wizards
数据集中的正则表达式模式,如下所示:
姓名 |
---|
哈利波特 |
罗恩·韦斯莱 |
赫敏格兰杰 |
您可以使用以下方式生成它:
DATA wizards;
INPUT Name $64.;
DATALINES;
Harry Potter
Ron Weasley
Hermione Granger
;
RUN
并输出一个
want
数据集,如下所示:
索引 | 巫师 | 积分 | 巫师1 | 巫师2 |
---|---|---|---|---|
1 | 哈利·波特罗恩·韦斯莱 | 100 | 哈利波特 | 罗恩·韦斯莱 |
2 | 赫敏格兰杰哈利波特 | 200 | 赫敏格兰杰 | 哈利波特 |
3 | 罗恩·韦斯莱 | 300 | 罗恩·韦斯莱 | . |
Wizard1
,Wizard2
...WizardN
中的结果需要是位置的:例如 在 hogwarts
Hermione Granger 的第 2 行,图案首先出现在 Wizards
列中,然后出现 Harry Potter,因此 Wizard1
中 want
的值需要为 Hermione Granger。
wizards
中的模式也可以由一个、两个或两个以上的单词组成,而Wizards
是hogwarts
中的多列,其中值由空格分隔,因此我们无法计算空格的数量每个模式之间要修复。
加上
Wizard1-WizardN
列的数量不是预先确定的。
有人知道吗?
提前非常感谢,
您可以使用正则表达式来检测向导列表中单词边界上的名称。 PRXMATCH 函数将返回列表中进行匹配的位置,并且该位置用于对所有匹配的表进行排序。 最后,TRANSPOSE 可以将您的匹配表转换为您想要的“跨”结构。
示例:
数据交叉是外连接,这意味着霍格沃茨的每一行与巫师的每一行都有一些比较。 在示例中,向导存储在临时数组中,用于测试断言正匹配的相应正则表达式也是如此。
DATA hogwarts;
INFILE DATALINES delimiter="," dsd;
LENGTH Index 8 Wizards $ 255;
INPUT Index Wizards $ Points;
DATALINES;
1,'Harry Potter Ron Weasley',100
2,'Hermione Granger Harry Potter',200
3,'Ron Weasley',300
;
DATA wizards;
INPUT Name $64.;
DATALINES;
Harry Potter
Ron Weasley
Hermione Granger
;
proc sql;
select count(name) into :name_count from wizards ;
data found ;
array wzname [&name_count] $64 _temporary_ ;
array rx [&name_count] _temporary_ ;
if 0 then set hogwarts; /* prep PDV */
if _n_ = 1 then do _n_ = 1 by 1 until (end_wizards);
set wizards end=end_wizards ;
wzname [_n_] = name ;
rx[_n_] = prxparse('m/\b'||trim(name)||'\b/i') ;
end ;
set hogwarts ;
do _n_ = 1 to dim(rx) ;
pos = prxmatch (rx[_n_],wizards) ;
if pos then do ;
name = wzname[_n_] ;
output ;
end ;
end ;
run ;
proc sort data=found ;
by index pos ;
run ;
proc transpose data=found out=want(drop=_name_) prefix=wizard;
by index wizards points ;
var name ;
run ;