我有 2 个数据集:一个包含一般商品列表,另一个包含交易列表:
关键字 | 商品 |
---|---|
肥皂A | 肥皂 |
肥皂B | 肥皂 |
洗发水 | 洗发水 |
身份证 | 日期 | Txn |
---|---|---|
1 | 1/22 | 肥皂A 100毫升 |
1 | 1/23 | 肥皂A 50毫升 |
2 | 1/24 | 肥皂B 100毫升 |
2 | 1/24 | 洗发水50毫升 |
3 | 1/24 | 果汁100克 |
我想创建如下所示的内容,检查 txn 列是否与关键字列匹配,并为每个 ID 的每个商品创建一个标记(例如,如果 ID 具有任何带有关键字“Soap A”或“Soap B”的 txns,则如果没有的话,Soap 列将被标记为 1 和 0)
身份证 | 肥皂 | 洗发水 |
---|---|---|
1 | 1 | 0 |
2 | 1 | 1 |
3 | 0 | 0 |
我知道我可以通过使用 if then 语句手动编码来实现这一点,但我有一长串商品,所以我想看看是否有更有效的方法通过 do 循环来实现这一点。
这是一种方法:
*create fake data;
data lookup;
infile cards dlm=',';
input Keyword $ Goods $;
cards;
Soap A, Soap
Soap B, Soap
Shampoo, Shampoo
;
run;
data rawData;
infile cards dlm=',' truncover;
input ID $ _Date $ Txn $25.;
informat id $8. _date $8. txn $25.;
date = mdy(input(scan(_date, 1, "/"), 8.), 1, input(scan(_date, 2, "/"), 8.));
format date yymmn6.;
drop _date;
cards;
1, 1/22, Soap A 100 ml
1, 1/23, Soap A 50 ml
2, 1/24, Soap B 100 ml
2, 1/24, Shampoo 50 ml
3, 1/24, Juice 100 g
;
run;
*get the dimensions of the number of lookup terms;
proc sql noprint;
select count(*) into :num_search_terms from lookup;
quit;
%put &num_search_terms;
*lookup values;
data search;
array _lookup(&num_search_terms., 2) $ _temporary_;
/*2*/
*load array into memory;
if _n_ = 1 then do j=1 to &num_search_terms.;
set lookup;
_lookup(j,1) = keyword;
_lookup(j,2) = Goods;
end;
set rawData;
do i=1 to &num_search_terms.;
if find(txn, _lookup(i, 1), 'it')>0 then term=_lookup(i, 2);
end;
if not missing(term) then Value=1;
drop i j keyword;
run;
*summarize to one record per id, term;
proc sql;
create table data2transpose as
select id, term, max(value) as Value
from search
group by id, term
order by 1;
quit;
*flip to desired format;
proc transpose data=data2transpose out=want;
by id;
var value;
id term;
run;