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

Sas 将数据集中的值加载到数组中,并在数据步骤中使用它们,sas,Sas,我有5个单独的数据集(实际上更多,但我想缩短代码),分别命名为dk33、dk34、dk35、dk51、dk63,每个数据集包含一个数字字段:surv_probs。我想将这些值加载到5个数组中,然后在一个datastep(result)中使用这些数组,但是,我需要建议什么是最好的方法 当我使用宏:setarrays:(下面的代码)时,我遇到了错误 这是主要代码 %let var1 = dk33; %let var2 = dk34; %let var3 = dk35; %let var4 = dk5

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

当我使用宏:setarrays:(下面的代码)时,我遇到了错误

这是主要代码

%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;
  • 对汤姆问题的答复:
*宏getlength(执行时)创建5个宏变量,命名为:dk33_行、dk34_行、dk35_行、dk51_行、dk63_行

*宏读取(执行时):创建5个宏变量dk33_列表、dk34_列表、dk35_列表、dk51_列表、dk63_列表。每个包含逗号的字符串将值与列分开:例如:0.99994,0.1999,0.1111

*宏setarrays在执行时创建5个数组,dk33_arr、dk34_arr、,。。。持有readin创建的宏变量的解析值,我发现“宏数组”如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;

看起来你想做一些矩阵操作。您是否有使用PROC IML的许可证?在尝试创建宏以生成SAS代码之前,您应该确保知道要生成的SAS代码。您能给出一个您希望宏生成的可工作SAS代码的示例吗?我尝试使用proc IML语句,但遇到错误:Procedure IML not found@TomI回答了您上面的问题@TomI也许我可以使用宏readin创建的内容来访问所需的值,而不是使用数组
data test;
  if _n_=1 then do;
    set dk33_t ;
    array dk33 dk33_: ;
  end;
  ....
run;