将数据集中的值加载到数组中,并在数据步骤中使用它们

时间:2018-07-29 22:27:46

标签: sas

我有5个独立的数据集(实际上更多,但我想简化代码),分别为dk33,dk34,dk35,dk51,dk63,每个数据集都包含一个数字字段:surv_probs。我想将值加载到5个数组中,然后在datastep(result)中使用这些数组,但是,我需要建议什么是最好的方法。

使用宏时出现错误:setarrays:(下面的代码)

WARNING: The quoted string currently being processed has become more than 262 characters long.  You might have unbalanced quotation 
         marks.
WARNING: The quoted string currently being processed has become more than 262 characters long.  You might have unbalanced quotation 
         marks.
ERROR: Illegal reference to the array dk33_arr.

这是主要代码。

%let var1 = dk33;
%let var2 = dk34;
%let var3 = dk35;
%let var4 = dk51;
%let var5 = dk63;
%let varN = 5;

/*put length of each column into macro variables */
%macro getlength;
%do i=1 %to &varN;
proc sql noprint;
     select count(surv_probs)
     into : &&var&i.._rows
     from work.&&var&i; 
quit;
%end;
%mend;

/*load values of column:surv_probs into macro variables*/
%macro readin;
%do i=1 %to &varN;
proc sql noprint;
select surv_probs 
into: &&var&i.._list  separated by "," 
from &&var&i;
quit;
%end;
%mend;

data _null_;
call execute('%readin');
call execute('%getlength');
run;

/* create arrays*/
%macro setarrays;
%do i=1 %to 1;
j=1;
array &&var&i.._arr{&&&&&&var&i.._rows};
do while(scan("&&&&&&var&i.._list",j,",") ne "");
&&var&i.._arr = scan("&&&&&&var&i.._list",j,",");
    j=j+1;
    end;
%end;
%mend;


data result;
%setarrays
put dk33_arr(1); 
* some other statements where I use the arrays*
run;
  • 回答汤姆斯问题:

* macro getlength(执行时)创建5个名为dk33_rows,dk34_rows,dk35_rows,dk51_rows,dk63_rows的宏变量

*宏读取(执行时):创建5个宏变量dk33_list,dk34_list,dk35_list,dk51_list,dk63_list。每个包含逗号的字符串都将值与列分开:例如:0.99994,0.1999,0.1111

*宏setarrays创建5个数组,执行时会包含dk33_arr,dk34_arr,...,其中包含从readin创建的宏变量中解析出的值

1 个答案:

答案 0 :(得分:1)

我发现像VAR1,VAR2,....这样的“宏数组”通常比它们值得的麻烦更多。将您的数据集名称列表保留在实际数据集中,然后从中生成代码。或者,如果列表足够短,则将列表放入单个宏变量中,然后使用%SCAN()来根据需要提取项目。

但是无论哪种方式,最好避免尝试编写需要三个以上&的宏代码。分多个步骤建立参考。构建一个具有要引用的宏名称的宏变量,然后将其值提取到另一个宏变量中。可能需要花费更多的代码行,但是您可以更轻松地了解正在发生的事情。

%let i=1 ;
%let mvarname=var&i;
%let dataset_name=&&&mvarname;

在开始使用宏代码(或其他代码生成技术)之前,请确保您知道要生成的代码。如果要将变量加载到临时数组中,则可以使用DO循环。不需要宏代码,也不需要将值甚至计数复制到宏变量中。例如,除了获取观测值的计数之外,您还可以仅使临时数组比预期的要大。

data test1 ;
  if _n_=1 then do;
    do i=1 to nobs_dk33;
      array dk33 (1000) _temporary_;
       set dk33 nobs=nobs_dk33 ;
       dk33(i)=surv_probs;
    end;
    do i=1 to nobs_dk34;
      array dk34 (1000) _temporary_;
       set dk34 nobs=nobs_dk34 ;
       dk34(i)=surv_probs;
    end;
  end;
* What ever you are planning to do with the DK33 and DK34 arrays ;
run;

或者您可以先转置数据集。

proc transpose data=dk33 out=dk33_t prefix=dk33_ ;
  var surv_probs ;
run;

然后,您只需使用SET语句就可以读取包含所有值的一个观察值。

data test;
  if _n_=1 then do;
    set dk33_t ;
    array dk33 dk33_: ;
  end;
  ....
run;