如何在 SAS 中为 DATA MERGE 编写灵活编号的 table 列表?
How to code a flexible numbered table list for DATA MERGE in SAS?
我有一个程序可以合并任意数量的连续编号的表。我尝试使用宏变量但无济于事。不断弹出错误“编号数据集列表上缺少数字后缀”。
这是有缺陷的代码:
DATA INPUTF;
INPUT DSN $;
CARDS;
forum1
forum2
forum3
;
RUN;
DATA forum1;
INPUT contact $ forum1 $;
CARDS;
Mash HERE
Greg HERE
Bob HERE
;
PROC SORT DATA=forum1;
BY contact;
RUN;
DATA forum2;
INPUT contact $ forum2 $;
CARDS;
Mash HERE
Sid HERE
Bob HERE
;
RUN;
PROC SORT DATA=forum2;
BY contact;
RUN;
DATA forum3;
INPUT contact $ forum3 $;
CARDS;
Mash HERE
Sid HERE
Jim HERE
;
RUN;
PROC SORT DATA=forum3;
BY contact;
RUN;
PROC SQL NOPRINT;
SELECT COUNT(*) INTO :n FROM INPUTF;
QUIT;
%MACRO COMBINE(N);
DATA ALLIN;
MERGE forum1-forum&n.;
BY contact;
RUN;
%MEND COMBINE;
%COMBINE;
PROC PRINT DATA=ALLIN;
然而,当我使用如下 %LET 语句时,代码工作正常:
%let n=3;
DATA ALLIN;
MERGE forum1-forum&n.;
BY contact;
RUN;
PROC PRINT DATA=ALLIN;
问题是我不知道有多少个论坛,我希望这个数字基于输入文件。
感谢任何帮助!谢谢!
宏变量作用域。
您已经创建了一个存在于全局 table 中的宏变量 N
。当您创建宏时,它需要一个参数,也称为 N
,它是本地的且未定义的,因为您没有传递有效参数。
使用创建的参数 N 调用您的宏或将过程 SQL 移动到宏中。
%COMBINE(&N);
或
%MACRO COMBINE;
PROC SQL NOPRINT;
SELECT COUNT(*) INTO :n FROM INPUTF;
QUIT;
DATA ALLIN;
MERGE forum1-forum&n.;
BY contact;
RUN;
%MEND COMBINE;
%COMBINE;
或
如果您只有 table 个以 FORUM 开头的要合并的文件:
DATA ALLIN;
MERGE FORUM: ;
BY contact;
RUN;
因此,如果您的数据集 InputF 包含要合并的数据集列表,请将该列表放入宏变量中。如果您始终至少有两个数据集,则不需要宏逻辑。
proc sql noprint ;
select dsn into :dsnlist separated by ' '
from inputf;
quit;
data allin;
merge &dsnlist ;
by contact;
run;
要处理列表中有 0 个或 1 个数据集名称的情况,您需要添加宏逻辑。当只有一个时,您需要使用 SET 而不是 MERGE。您可以使用 IFC() 函数来处理它。
data allin;
%sysfunc(ifc(1=&sqlobs,set,merge)) &dsnlist ;
by contact;
run;
我有一个程序可以合并任意数量的连续编号的表。我尝试使用宏变量但无济于事。不断弹出错误“编号数据集列表上缺少数字后缀”。
这是有缺陷的代码:
DATA INPUTF;
INPUT DSN $;
CARDS;
forum1
forum2
forum3
;
RUN;
DATA forum1;
INPUT contact $ forum1 $;
CARDS;
Mash HERE
Greg HERE
Bob HERE
;
PROC SORT DATA=forum1;
BY contact;
RUN;
DATA forum2;
INPUT contact $ forum2 $;
CARDS;
Mash HERE
Sid HERE
Bob HERE
;
RUN;
PROC SORT DATA=forum2;
BY contact;
RUN;
DATA forum3;
INPUT contact $ forum3 $;
CARDS;
Mash HERE
Sid HERE
Jim HERE
;
RUN;
PROC SORT DATA=forum3;
BY contact;
RUN;
PROC SQL NOPRINT;
SELECT COUNT(*) INTO :n FROM INPUTF;
QUIT;
%MACRO COMBINE(N);
DATA ALLIN;
MERGE forum1-forum&n.;
BY contact;
RUN;
%MEND COMBINE;
%COMBINE;
PROC PRINT DATA=ALLIN;
然而,当我使用如下 %LET 语句时,代码工作正常:
%let n=3;
DATA ALLIN;
MERGE forum1-forum&n.;
BY contact;
RUN;
PROC PRINT DATA=ALLIN;
问题是我不知道有多少个论坛,我希望这个数字基于输入文件。
感谢任何帮助!谢谢!
宏变量作用域。
您已经创建了一个存在于全局 table 中的宏变量 N
。当您创建宏时,它需要一个参数,也称为 N
,它是本地的且未定义的,因为您没有传递有效参数。
使用创建的参数 N 调用您的宏或将过程 SQL 移动到宏中。
%COMBINE(&N);
或
%MACRO COMBINE;
PROC SQL NOPRINT;
SELECT COUNT(*) INTO :n FROM INPUTF;
QUIT;
DATA ALLIN;
MERGE forum1-forum&n.;
BY contact;
RUN;
%MEND COMBINE;
%COMBINE;
或
如果您只有 table 个以 FORUM 开头的要合并的文件:
DATA ALLIN;
MERGE FORUM: ;
BY contact;
RUN;
因此,如果您的数据集 InputF 包含要合并的数据集列表,请将该列表放入宏变量中。如果您始终至少有两个数据集,则不需要宏逻辑。
proc sql noprint ;
select dsn into :dsnlist separated by ' '
from inputf;
quit;
data allin;
merge &dsnlist ;
by contact;
run;
要处理列表中有 0 个或 1 个数据集名称的情况,您需要添加宏逻辑。当只有一个时,您需要使用 SET 而不是 MERGE。您可以使用 IFC() 函数来处理它。
data allin;
%sysfunc(ifc(1=&sqlobs,set,merge)) &dsnlist ;
by contact;
run;