Loops 不等长循环

Loops 不等长循环,loops,sas,increment,do-loops,Loops,Sas,Increment,Do Loops,我有很多sas数据集文件,以“s”开头,后面是一些数字,如s1 s7 s13 s32等(我有很多)。 对于运行一组代码的每个文件,保存上一个结果,然后使用以下数据集文件重新启动。通常,当我的数据集文件编号按顺序排列时,如s1 s2 s3 s4 s5…很容易使用,例如a%do i=1%到120。但是如果我想做一个不等增量的循环呢?我该怎么做?比如一个%doi=1 7 13 32…。这在MATLAB中很容易,但在SAS中我不太确定如何实现 以下示例获取数据集S1、S3和S10并对其进行处理,输出数据

我有很多sas数据集文件,以“s”开头,后面是一些数字,如s1 s7 s13 s32等(我有很多)。
对于运行一组代码的每个文件,保存上一个结果,然后使用以下数据集文件重新启动。通常,当我的数据集文件编号按顺序排列时,如s1 s2 s3 s4 s5…很容易使用,例如a
%do i=1%到120
。但是如果我想做一个不等增量的循环呢?我该怎么做?比如一个
%doi=1 7 13 32…
。这在MATLAB中很容易,但在SAS中我不太确定如何实现

以下示例获取数据集S1、S3和S10并对其进行处理,输出数据集NEW1、NEW3和NEW10:

/* Example data sets */
data s1 s3 s10;
run;

%macro mymac;

  /* Create 'array' of macro variables DSET1, DSET2...up to a max of DSET9999.
     Each DSETx macro variable will contain a data set number. */
  proc sql noprint;
    select compress(memname,"sS") into :dset1-:dset9999
    from sashelp.vtable
    where libname="WORK" and upcase(substr(memname,1,1))="S"
          and input(compress(memname,"sS"),8.) ne .;
  quit;
  %let numdsets=&sqlobs;

  /* Process data sets */    
  %do i=1 %to &numdsets.;
    data new&&dset&i.;
      set s&&dset&i.;
    run;
  %end;
%mend mymac;
%mymac

您可以在正常do循环中执行非顺序增量,但在宏do循环中不能以相同的方式执行。SAShelp网站上有一个变通方法

我首先使用下面的代码将这些数字放在逗号分隔的宏列表中。prxmatch函数搜索以“S”开头,后跟数字的数据集名称。一旦你有了这个,你可以按照SAS网站上的代码

proc sql noprint;
select compress(upper(memname),'S') into :ds_num separated by ',' from dictionary.tables
where libname='WORK' and prxmatch("/S\d+/",upper(memname));
quit;

%put &ds_num.;

%我是你的朋友。请看下面的示例代码-

%let nums = 1 2 4 6 13 29 32;

%macro iter();

%let cnt = %sysfunc(countc(&nums," "));
%let cnt = %eval(&cnt + 1);
%put &cnt;

%do i = 1 %to &cnt;
%put I will now process dataset s%scan(&nums,&i," ");
%end;

%mend iter;

%iter()

您可以修改零件%put。。。写入数据步骤。

使您的%do从最低的数据集编号到最高的数据集编号。然后检查数据集是否存在

%Let lib=yourlib;
%Macro Process;

 %Do i = 1 %to 1000;
  %if %sysfunc(exist(&lib..s&i)) %then %do;

    <your code>

  %end;

 %end;

%Mend process;
%process
%Let lib=yourlib;
%宏观过程;
%i=1%到1000;
%如果%sysfunc(存在(&lib..s&i))%,则%do;
%结束;
%结束;
%修补工艺;
%过程

这是对Mozan上述答案的更新。我不建议使用CountC来计算列表中的元素。 改用CountW。注:更新如下:

%let nums = 1 2 4 6 13 29 32;

%macro iter();

%let cnt = %sysfunc(CountW(&nums));
%put &cnt;

%do i = 1 %to &cnt;
  %put I will now process dataset s%scan(&nums,&i);
%end;

%mend iter;

%iter()

你的代码将是完美的另一批库文件,我将不得不通过。谢谢!您能解释一下后面的内容吗
%let cnt=%sysfunc(countc(&nums,”);%让cnt=%eval(&cnt+1)据我所知,您首先在
%let nums
中计算总数/条目,但为什么
&cnt+1
?您问得好!这是因为,如上所述,COUNTC函数告诉您字符串NUMS中有多少空格。只要NUMS宏变量在标记之间正好有一个空格,就需要添加一个空格来查看存在多少标记。但是要小心:例如,
%让nums=12
有四个空格(所以CNT应该是五个)。[在%let stmt的示例中,我似乎无法让此便笺显示连续的空格。]@BobDuell,说得好。是的,COUNTC通常用于计算特定字符在字符串中出现的次数。在这里,我们必须将它与%SYSFUNC结合使用,因为我们要将它应用于宏变量。在这种情况下,必须仔细编写%LET nums部分,以确保没有多余的空格,或者另一个选项是使用COMPBL(再次与sysfunc一起)进行额外检查。我个人更喜欢管道,并且总是将其写成%let nums=1 | 2 | 3;