SAS循环数据集

SAS循环数据集,sas,Sas,我在库调用snap1中有多个表: 客户1、客户2、客户3等 我想生成一个循环,获取每个表中相同列的记录计数,然后将结果插入到不同的表中 我期望的输出是: Table Count cust1 5,000 cust2 5,555 cust3 6,000 我正在尝试,但它不起作用: %macro sqlloop(data, byvar); proc sql noprint; select &byvar.into:_values SEPARATED by '_' from %data.; q

我在库调用snap1中有多个表:

客户1、客户2、客户3等

我想生成一个循环,获取每个表中相同列的记录计数,然后将结果插入到不同的表中

我期望的输出是:

Table Count

cust1 5,000
cust2 5,555
cust3 6,000
我正在尝试,但它不起作用:

%macro sqlloop(data, byvar);
proc sql noprint;
select &byvar.into:_values SEPARATED by '_'
from %data.;
quit;
data_&values.;
set &data;
select (%byvar);

%do i=1 %to %sysfunc(count(_&_values.,_));
%let var = %sysfunc(scan(_&_values.,&i.));
output &var.;
%end;
end;

run;
%mend;

%sqlloop(data=libsnap, byvar=membername);
*已更新*

将来,请发布日志,以便我们可以看到哪些具体不起作用。我可以在代码中看到一些问题,特别是在声明宏变量的地方,以及一个没有做任何事情的
select
语句。以下是实现目标的另一个过程:

步骤1:
snap1
库中的所有客户数据集读取到宏变量中:

proc sql noprint;
    select memname
    into :total_cust separated by ' '
    from sashelp.vmember
    where upcase(memname) LIKE 'CUST%'
          AND upcase(libname) = 'SNAP1';
quit;
步骤2:计算每个数据集中OB的总数,输出到永久表:

 %macro count_obs;
      %do i = 1 %to %sysfunc(countw(&total_cust) );
           %let dsname = %scan(&total_cust, &i);

           %let dsid=%sysfunc(open(&dsname) );
           %let nobs=%sysfunc(attrn(&dsid,nobs) );
           %let rc=%sysfunc(close(&dsid) );

           data _total_obs;
                length Member_Name $15.;
                Member_Name = "&dsname";
                Total_Obs = &nobs;

                format Total_Obs comma8.; 
           run;

           proc append base=Total_Obs
                       data=_total_obs;
           run;
     %end;

     proc datasets lib=work nolist;
         delete _total_obs;
     quit;

 %mend;
 %count_obs;
如果永久表已经存在,则需要删除该表,但如果愿意,可以添加代码来处理该表

如果要获取特定列的未丢失观测值总数,请执行与上面相同的代码,但删除下面的3个
%let
语句
%let dsname=
,并将
数据
步骤替换为:

data _total_obs;
     length Member_Name $7.;
     set snap1.&dsname end=eof;
     retain Member_Name "&dsname";

     if(NOT missing(var) ) then Total_Obs+1;

     if(eof);

     format Total_Obs comma8.;
run;

(更新:修复了步骤2中的%do循环)

*已更新*

将来,请发布日志,以便我们可以看到哪些具体不起作用。我可以在代码中看到一些问题,特别是在声明宏变量的地方,以及一个没有做任何事情的
select
语句。以下是实现目标的另一个过程:

步骤1:
snap1
库中的所有客户数据集读取到宏变量中:

proc sql noprint;
    select memname
    into :total_cust separated by ' '
    from sashelp.vmember
    where upcase(memname) LIKE 'CUST%'
          AND upcase(libname) = 'SNAP1';
quit;
步骤2:计算每个数据集中OB的总数,输出到永久表:

 %macro count_obs;
      %do i = 1 %to %sysfunc(countw(&total_cust) );
           %let dsname = %scan(&total_cust, &i);

           %let dsid=%sysfunc(open(&dsname) );
           %let nobs=%sysfunc(attrn(&dsid,nobs) );
           %let rc=%sysfunc(close(&dsid) );

           data _total_obs;
                length Member_Name $15.;
                Member_Name = "&dsname";
                Total_Obs = &nobs;

                format Total_Obs comma8.; 
           run;

           proc append base=Total_Obs
                       data=_total_obs;
           run;
     %end;

     proc datasets lib=work nolist;
         delete _total_obs;
     quit;

 %mend;
 %count_obs;
如果永久表已经存在,则需要删除该表,但如果愿意,可以添加代码来处理该表

如果要获取特定列的未丢失观测值总数,请执行与上面相同的代码,但删除下面的3个
%let
语句
%let dsname=
,并将
数据
步骤替换为:

data _total_obs;
     length Member_Name $7.;
     set snap1.&dsname end=eof;
     retain Member_Name "&dsname";

     if(NOT missing(var) ) then Total_Obs+1;

     if(eof);

     format Total_Obs comma8.;
run;


(更新:在步骤2中修复了%do循环)

首先,如果您只需要观察的数量,您可以从没有任何循环的
dictionary.tables
sashelp.vtable
中获得

proc sql;
  select memname, nlobs
    from dictionary.tables
    where libname='SNAP1';
quit;
如果您没有做任何会导致逻辑观察数不同的事情(通常是proc sql中的删除),则可以检索行数

其次,如果您对有效响应的数量感兴趣,也有更简单的非循环方法

例如,给定您可以编写的用于确定表名的任何查询,我们可以将它们全部放在
set
语句中,并在一个简单的数据步骤中进行计数

%let varname=mycol; *the column you are counting;
%let libname=snap1;


proc sql;
  select cats("&libname..",memname) 
    into :tables separated by ' '
    from dictionary.tables
    where libname=upcase("&libname.");
quit;

data counts;
  set &tables. indsname=ds_name end=eof; *9.3 or later;
  retain count dataset_name;
  if _n_=1 then count=0;
  if ds_name ne lag(ds_name) and _n_ ne 1 then do;
    output;
    count=0;
  end;
  dataset_name=ds_name;
  count = count + ifn(&varname.,1,1,0);  *true, false, missing;  *false is 0 only;
  if eof then output;
  keep count dataset_name;
run;
这类事情很少需要宏,像您正在编写的宏循环就更不需要了

如果确实要编写宏,更简单的方法是:

  • 为一个数据集编写一次代码
  • 将其包装在接受参数(数据集名称)的宏中
  • 根据需要为该宏创建宏调用
这样,您就不必处理
%scan
和疑难解答难以调试的宏代码。你只写一次有效的东西,然后多次调用它

proc sql;
  select cats('%mymacro(name=',"&libname..",memname,')') 
    into :macrocalls separated by ' '
    from dictionary.tables
    where libname=upcase("&libname.");
quit;

&macrocalls.;

假设您有一个宏,
%mymacro
,它可以对一个数据集执行任何您想要的计数。

首先,如果您只需要观察的数量,您可以从没有任何循环的
字典.tables
sashelp.vtable
中轻松获得

proc sql;
  select memname, nlobs
    from dictionary.tables
    where libname='SNAP1';
quit;
如果您没有做任何会导致逻辑观察数不同的事情(通常是proc sql中的删除),则可以检索行数

其次,如果您对有效响应的数量感兴趣,也有更简单的非循环方法

例如,给定您可以编写的用于确定表名的任何查询,我们可以将它们全部放在
set
语句中,并在一个简单的数据步骤中进行计数

%let varname=mycol; *the column you are counting;
%let libname=snap1;


proc sql;
  select cats("&libname..",memname) 
    into :tables separated by ' '
    from dictionary.tables
    where libname=upcase("&libname.");
quit;

data counts;
  set &tables. indsname=ds_name end=eof; *9.3 or later;
  retain count dataset_name;
  if _n_=1 then count=0;
  if ds_name ne lag(ds_name) and _n_ ne 1 then do;
    output;
    count=0;
  end;
  dataset_name=ds_name;
  count = count + ifn(&varname.,1,1,0);  *true, false, missing;  *false is 0 only;
  if eof then output;
  keep count dataset_name;
run;
这类事情很少需要宏,像您正在编写的宏循环就更不需要了

如果确实要编写宏,更简单的方法是:

  • 为一个数据集编写一次代码
  • 将其包装在接受参数(数据集名称)的宏中
  • 根据需要为该宏创建宏调用
这样,您就不必处理
%scan
和疑难解答难以调试的宏代码。你只写一次有效的东西,然后多次调用它

proc sql;
  select cats('%mymacro(name=',"&libname..",memname,')') 
    into :macrocalls separated by ' '
    from dictionary.tables
    where libname=upcase("&libname.");
quit;

&macrocalls.;

假设您有一个宏,
%mymacro
,它可以对一个数据集进行任何您想要的计数。

您能更好地解释一下您想要什么吗?示例输入和输出会有所帮助。在尝试创建宏之前,请确保您知道如何为特定情况编写代码。然后,您可以开始编写一个宏,为其他情况生成该代码。现在宏没有生成任何有效的SAS代码。该代码与结果有什么关系?它不会做任何与你所说的你想要的无关的事情。你能更好地解释你想要什么吗?示例输入和输出会有所帮助。在尝试创建宏之前,请确保您知道如何为特定情况编写代码。然后,您可以开始编写一个宏,为其他情况生成该代码。现在宏没有生成任何有效的SAS代码。该代码与结果有什么关系?它根本不会做任何与您所说的内容相关的事情。这是可行的,但表的名称不完全是cust1、cust2等。如何让代码打印出确切的名称?使用更通用的解决方案更新