我有一个宏观相关的问题,我正在努力发展和理解。任何解决这个问题的指针都将非常感激: - )
下面有类似的内容:
我有'n'[变量]数量的宏变量'Key'解析为
& Key1 = 1& Key = 2& Key3 = 3 ............... .. .......... &安培; Keyn = N
我想创建一个自动运行的宏'Masterkey',类似于
& Masterkey = 1& Masterkey2 = 12& Masterkey = 123 .......... .........。
即。 &安培; MasterKeyN = 123 ...... ...... N
我怎样才能创建'& MasterkeyN',其中N未固定,因为可以根据[1-n]个键的每组情况进行变量?
非常感谢。
纳德
答案 0 :(得分:1)
我认为这可能不是一种有用的技巧,但无论如何我都会回答它。
我还假设&Key1..n
可能包含存储在其中的数字以外的值,并且您希望将这些值收集到&MasterKey1..n
变量中。
您需要做的是使用嵌套循环,并了解宏变量如何解决。
%let key1=A;
%let key2=B;
%let key3=C;
%global MasterKey1 MasterKey2 MasterKey3; *so they work outside of the macro;
%macro create_master(numKeys=);
%do master=1 %to &numKeys; *Outer loop for the MasterKeys we want to make;
%let temp=;
%do keyiter = 1 %to &master; *Inner loop for the keys that fall into the MasterKey;
%let temp = &temp.&&Key&keyiter.; *&& delays macro variable resolution one time.;
%end;
%let MasterKey&master.=&temp.;
%end;
%mend create_master;
%create_master(numkeys=3);
%put &=MasterKey1 &=MasterKey2 &=MasterKey3;
这里的魔力是&&
。基本上,在宏变量解析期间,您一次只处理一个或两个。如果它有助于在循环中放置一些%put
语句来查看它是如何工作的。
首先,让我们跳到最后。在此次迭代中,&temp=AB
&Keyiter=3
和&Key3=C
。
0. &temp.&&Key&keyiter
1. AB&Key3
2. ABC
因此,从0到1,解析器会看到&temp.
,表示一个变量结束的句点,所以它会查找那个:&temp.=AB
并用AB替换它。然后它会看到两个&
,并用一个&
替换它们,但不会尝试用它们解决任何问题。然后它看到Key
,那里没有&符号,所以没什么可做的。然后它会看到&keyiter
,好吧,用3
替换它。
然后从1到2,它看到AB
,忽略它应该。然后它看到&Key3
(两个&符号变成了一个不要忘记),现在它知道将其解析为C
,它确实如此 - 因此ABC。
答案 1 :(得分:0)
非常感谢大家提供的有用评论和解决方案。是的,绝对可以通过多种方式在SAS中提供解决方案。我可能从一个角度着手接近这个问题。无论如何,我现在能够解决这个问题。 以下是有关问题的简要概述和“以下解决方案:
”我有许多客户和交易表。目标是根据匹配类型+进程密钥和匹配键匹配/连接两个表(匹配键是表中的字段。 关于匹配的说明由类似于底部的表格给出。 我正在尝试构建一个宏,其中包含基于某些匹配类型和进程密钥的连接指令,例如:对于匹配类型= Profile和Process key = 3,我想创建一个包含字符串的宏(下面的链接),然后可以将其输入proc sql命令: ]
Table1.Name=Table2.Name
And Table1.Address=Table2.Address
]
我根据匹配类型和进程键为每个匹配键创建了一个宏,并希望在第二个和后续键之前添加键[带'和'文本]的动态串联。我遇到的问题是,对于任何给定的匹配类型和进程密钥,没有固定数量的匹配键。
Matching_Type Process_Key Matching_Keys
Profile 1 Name
Profile 1 Address
Profile 1 Gender
Market 1 Name
Market 1 Income
Profile 2 Name
Profile 2 Address
Profile 2 Gender
Profile 2 DoB
Profile 2 Phone_Number
Market 2 Name
Market 2 Address
Market 2 Gender
Market 2 Income
Market 2 Transaction_Amount
Market 2 Credit_Card_Number
Profile 3 Name
Profile 3 Address
解决方案:
%macro test;
proc sql noprint;
select left(put(count(distinct matching_type||left(put(process_key,8.))),8.)) into :num
from test;
select distinct matching_type, process_key into :matchkey1 - :matchkey&num, :processkey1-:processkey&num
from test;
%do i=1 %to #
%global &&matchkey&i&&processkey&i;
select 'table1.'||trim(matching_keys)||' = table2.'||trim(matching_keys) into :&&matchkey&i&&processkey&i separated by ' and '
from test
where matching_type="&&matchkey&i" and process_key=&&processkey&i;
%end;
quit;
%mend;
options mprint;
%test;
%put _user_;
非常感谢大家。