我是sas的新手。我写了一个基本代码,但它没有用。有人可以帮我弄清楚代码有什么问题。我希望附加数据集。
options mprint mlogic symbolgen;
%macro temp();
%let count = 0;
%if &count = 0 %then %do;
data temp;
set survey_201106;
%let count = %eval(&count +1);
%end;
%else %do;
%do i = 201107 %to 201108;
data temp;
set temp survey_&i;
%end;
%end;
run;
%mend;
%temp;
答案 0 :(得分:1)
您在宏的开头设置&count
为0,因此永远不会执行%else
子句。
我不确定你的目标是什么,但看起来你只想连接3个数据集并存储在新的数据集中。如果是这样,这还不够:
data temp;
set survey_201106-survey_201108;
run;
这会创建一个名为temp的数据集,并按顺序使用survey_201106,survey_201107和survey_201108的内容填充它。 -
告诉SAS您希望Survey_201106和survey_201108之间的所有数据集名为survey_20110 *。
答案 1 :(得分:0)
options mprint mlogic symbolgen;
%macro temp();
proc sql noprint;
create table table_list as
select monotonic() as num,memname
from dictionary.tables
where libname = 'WORK' and memname contains 'SURVEY_';
quit;
proc sql noprint;
select count(*) into :cnt
from table_list;
quit;
%do i = 1 %to &cnt.;
%if &i eq 1 and %sysfunc(exist(work.temp)) %then %do;
proc sql;
drop table work.temp;
quit;
%end;
proc sql noprint;
select memname into :memname
from table_list
where num = &i.;
quit;
proc append base = temp data = &memname. force;
run;
%end;
%mend;
%temp;
工作:上面的代码将附加名称以?开头的所有工作数据集 '调查_'到临时数据集。
table_list数据集:
num memname
1 survey_201106
2. survey_201107
3. survey_201108
创建cnt宏变量以保存此类数据集的数量
在循环内,每个数据集呈现的数据集名称列表(在表table_list中)将附加到work.temp数据集
答案 2 :(得分:0)
您可能要做的是创建一个宏,当数据集存在时附加(由于某种原因不使用proc append
),或者在数据集存在时创建它。
SAS与r
或其他类似语言不同,您必须在很大程度上控制所发生的一切。 SAS的优势在于你可以要求它只使用一行或两行代码来做常见事情。由于这个原因,SAS通常被称为4th Generation Language
:你不应该控制所有的小位。那是浪费时间。使用程序(PROC ...)和构建SAS为您提供。
在这种情况下,PROC APPEND
完成了整个宏所做的事情。它创建一个数据集或向其添加新行(如果它已经存在)。
proc append base=temp data=in_data;
run;
现在,如果您正在尝试学习宏语言并仅将此概念用作学习工具,则可以在与您的宏不同的宏中执行此操作。
注意: 这是一个很好的方法。它可能对学习宏概念很有用,但不应该用作良好代码的示例。尽管我有所改进,但仍然不是应该这样做的方式; proc append
或SRSwift的例子更好。
我将在这里介绍一件事:一个宏参数。一个很好的宏编程规则是所有宏都应该有参数。如果没有可能的参数,通常应该可以不需要宏。在大多数情况下,参数是使宏有用的原因。在这种情况下,我将重写您的宏以将一个附加数据集作为参数和一个“基础”数据集。在您的示例中,temp
是基础数据集,survey_1106
等是附加数据集。
此外,&count
必须是global
宏变量。在SAS中,在宏内部创建的变量默认是在范围内本地 - 即,它们仅在宏的一次运行中定义然后消失。这几乎与c / etc中的函数相同。语言(与r有点不同,它使用词法作用域,你可能会期待你如何写这个)。虽然有一些有趣的规则,但是现在我们只是顺其自然。 global
宏变量(包括已在全局范围内定义的任何变量)在所有宏迭代中(以及宏外)都可用。
所以:
%macro append_dataset(base=,append=);
%if &count=0 %then %do;
data &base.;
set &append.;
run;
%end;
%else %do;
data &base.;
set &base. &append.;
run;
%end;
%let count=%eval(&count.+1);
%mend append_dataset;
%let count=0;
%append_dataset(base=temp,append=survey_1106);
%append_dataset(base=temp,append=survey_1107);
%append_dataset(base=temp,append=survey_1108);
现在,您可以通过外部方法(例如Harshad示例中的dictionary.tables)生成这些调用。您还可以向宏添加另一个元素,即迭代在append
提供的列表中的所有元素。您也可以在%do循环中对列表进行硬编码,就像您在初始示例中所做的那样(但我认为这是不好的做法)。你可以在我的宏中完成这个:
%macro append_dataset(base=,append=);
%do survey=201106 to 201108;
%if &count=0 %then %do;
data &base.;
set survey_&survey.;
run;
%end;
%else %do;
data &base.;
set &base. survey_&survey.s;
run;
%end;
%let count=%eval(&count.+1);
%end;
%mend append_dataset;
请注意,计数增量是里面 do循环 - 这是你在这里出错的地方之一。否则,这只是添加一个外部循环并将附加提及更改为循环中的计算值。但同样,这是一个相当差的编码实践 - 循环至少应该从宏参数构造。