【问题标题】:alternative to a macro variable替代宏变量
【发布时间】:2014-06-03 10:26:13
【问题描述】:

我编写了以下脚本,如下所示,它应该删除表中包含大约 70000 个变量的列。

在条件中我只给了你我的 SQL 脚本的一小部分。通常在所有条件都放好后,查询会检索我 6000 个变量-ish * 6。

宏变量 droplist_u 太小,无法保存所有内容。您是否有使用宏变量的替代方法并避免 报错“表达式长度(65535)超过最大长度(65534)”?

已编辑:获取下拉列表中的所有变量后,我将使用该命令行 %put droplist_u: &droplist_u; 将其转换为宏变量

%let pays1=IK ;

%do nopays=1 %to 1;

%do l=0 %to 5;

/*one off*/
proc sql;
select catt(nomvar,"_t&&l") into : droplist_u separated by ' ' from dico&&pays&nopays
where (intitule like 'RT1%' or intitule like '%RT12%'
or intitule like 'IS-PPI%'
or intitule like 'IS-IP%'
or intitule like 'IS-IP-SA%'
or intitule like 'IS-IMPR%'
or intitule like 'IS-IMPX%'
or intitule like 'IS-IMPZ%'
or intitule like 'B-E36%'
or intitule like 'B-D_F%'
or intitule like 'B-D%'
or intitule like 'B_C%'
or intitule like 'MIG_ING%'
or intitule like 'MIG_NRG%'
or intitule like 'MIG_CAG%'
or intitule like 'MIG_COG%'
or intitule like 'MIG_DCOG%'
or intitule like '%C191%'
or intitule like '%C192%'
or intitule like '%C20_C21%'
or intitule like '%C20%'
or intitule like '%C201%'
or intitule like '%C2011%'
or intitule like '%C2012%'
or intitule like '%C2013%'
or intitule like '%C2014%'
or intitule like '%C2015%'
or intitule like '%C2016%'
or intitule like '%C2017%'
or intitule like '%C202%'
or intitule like '%C203%'
or intitule like '%C204%'
or intitule like '%C2041%'
or intitule like '%C2042%'
or intitule like '%C205%'
or intitule like '%C2051%'
or intitule like '%C2052%'
or intitule like '%C2053%'
or intitule like '%C2059%'
or intitule like '%C206%'
or intitule like '%C21%'
or intitule like '%C211%'
or intitule like '%PCH_SM%');
quit;

%put droplist_u: &droplist_u;

data a&&pays&nopays;
set a&&pays&nopays (drop=&droplist_u);
run;

%end;
%end;
%mend;


%testsql;
run;`

【问题讨论】:

    标签: sql macros sas


    【解决方案1】:

    您可以尝试将数据步(代码)写入文本文件,然后 %include 将该文本文件 - 请参见下面的伪代码(未经测试):

    proc sql;
    create table vars as
    select catt(nomvar,"_t&&l") as var 
    from dico&&pays&nopays
    where (intitule like 'RT1%' or intitule like '%RT12%'
    or intitule like 'IS-PPI%'
    xxx
    xxx
    xxx
    ;quit;
    
    filename tempf temp;
    data _null_;
       file tempf;
       set vars end=lastobs;
       if _n_=1 then put "data a&&pays&nopays;set a&&pays&nopays (drop=";
       put var /;
       if lastobs then put ");run;";
    run;
    
    %inc tempf;
    
    filename tempf clear;
    

    请注意,通过处理如此大的数据集,您可能会遇到memory limits(显然取决于您的操作环境)

    【讨论】:

    • 您好 RawFocus,感谢您的回答。在继续之前,您了解我的脚本的目标吗?
    • 您正在检索要删除的变量,然后使用 datastep set 语句作为宏循环的一部分删除这些变量。我编辑了我的帖子 - 我了解你吗,你了解我吗?
    • 是的,你确实了解我。对不起,因为有时,我觉得我不够清楚,所以我澄清一下。 :)
    • 不用担心,@RawFocus。这只是一个温和的建议。
    • 经过长时间的讨论,我会采取其他方式,例如丢弃不需要的变量而不是保留想要的变量。为什么?我有一个想法要丢弃哪个,但那些处于波动状态,不知道我们是否保留其中一些。玩 SAS 与 SQL 结合后有点脑残。再次欢呼,@RawFocus。
    【解决方案2】:

    什么可以为您要删除的每一列创建一个单独的宏变量,其中包含一个序列号,并使用循环将它们全部放入保留中。

    %macro dropColumns;
    %let pays1=IK ;
    %do nopays=1 %to 1;
    data _null_;
     set dico&&pays&nopays 
     (where=(intitule like 'RT1%' 
      ...
      or intitule like '%PCH_SM%')) 
     end=last;
     %do l=0 %to 5;
      count + 1;
      call symput(cats('todelete',count),catt(nomvar,"_t&&l"));
     %end;
     if last then call symput('todeleteobs',count);
    run;
    
    data a&&pays&nopays;
     data a&&pays&nopays (drop=
     %do i = 1 %to &todeleteobs.;
      &&todelete&i.
     %end;
     );
    run;
    
    %end;
    %mend;
    
    %dropColumns;
    

    【讨论】:

    • 我去看看。谢谢洛朗。
    • 这也可以——所以你有几千个较小的宏变量,而不是一个大的宏变量。而且,正如正确地暗示的那样,这些宏变量一旦完成就应该被删除。虽然,假设它们具有本地范围(未全局声明),它们在宏执行后无论如何都会被删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多