简体   繁体   English

SAS:在数据步骤中将宏变量用作数字

[英]SAS: Utilizing macro variables as numbers in data step

I am touching up some SAS code I wrote and found a chunk of code I wish to execute more effectively. 我正在整理一些我编写的SAS代码,发现了我希望更有效执行的一大堆代码。 I have a time-series data set called 'Forecasts' which just consists of date and the 'Forecast' variable for a given date. 我有一个名为“ Forecasts”的时间序列数据集,该数据集仅包含日期和给定日期的“ Forecast”变量。

I wrote a simple block of code to take this variable and basically chop it up into a series of variables, each one representing one date: 我编写了一个简单的代码块来获取此变量,并基本上将其分成一系列变量,每个变量代表一个日期:

data forecasts;
set forecasts;
  obs=_n_; 
  array r(241);
  do i=1 to dim(r);
    if obs=i then r(i)=Forecast;
  end; drop i; drop obs; drop forecast;
run;

However, the 'r(241)' part of this code really annoys me. 但是,这段代码的“ r(241)”部分确实让我很烦。 I already have a macro variable which corresponds to the number of times I need to perform this operation (called 'n'), and I would rather just plug it into the array proclamation directly, something like: 我已经有一个宏变量,它对应于执行此操作所需的次数(称为“ n”),我宁愿直接将其直接插入数组声明中,例如:

array r(&n)

etc. 等等

However macro variables are obviously considered text, so even when I managed to import the macro variable into the data step, variants r(&n) doesn't work because it doesn't read 'n' as a numeric. 但是,宏变量显然被认为是文本,因此即使我设法将宏变量导入数据步骤,变量r(&n)也不起作用,因为它没有将n读作数字。 Outside of wrapping this entire data step into a broader macro, how can I pull 'n' into the data step then convert it to a numeric so this operation works? 除了将整个数据步骤包装到一个更广泛的宏之外,我如何才能将“ n”拉入数据步骤,然后将其转换为数字,以便此操作有效?

The statement: 该声明:

array r(&n) ;

should be fine, assuming the macro variable is defined and has an integer value. 假设宏变量已定义且具有整数值,则应该没问题。 Please show how you are trying to use it (and any failing log messages). 请显示您如何尝试使用它(以及所有失败的日志消息)。 You don't need to 'import macro variables into the data step'. 您不需要“将宏变量导入数据步骤”。 Macro variables are text because their primary job is to resolve to SAS code. 宏变量是文本,因为它们的主要工作是解析为SAS代码。

18   %let n=3;
19   data _null_;
20     array r{&n};
21     do i=1 to dim(r);
22       put i=;
23     end;
24   run;

i=1
i=2
i=3

Just as a suggestion, you don't need to do it this way. 只是建议,您不需要这样做。 PROC TRANSPOSE exists for this purpose. 为此存在PROC TRANSPOSE Then you don't even have to know how many variables/rows there are. 然后,您甚至不必知道有多少个变量/行。

data forecast;
  call streaminit(7);
  do id = 1 to 243;
    forecast = rand('Normal')*5;
    output;
  end;
run;

proc transpose data=forecast out=forecasts prefix=r;
  by id;
  id id;
  var forecast;
run;

If you don't actually want 243 rows but want just one, dump the by and the id statements. 如果您实际上并不想要243行,而只想要一行,则转储byid语句。

Even if you wanted to do it in a data step, you could do this quite a bit faster (Right now you're checking 241 * 241 times, you only need 241 times...) by putting the set inside the loop. 即使你想要做一个数据的步骤,你可以这样做相当快一点通过将(现在你正在检查241 * 241倍,你只需要241次......) set内循环。 Here I use the automatically dropped variable _n_ to iterate the loop. 在这里,我使用自动删除的变量_n_来迭代循环。

data forecasts;
  do _n_ = 1 by 1 until (eof);
    set forecast end=eof;
    array r(243);
    r[_n_] = forecast;
    output; *if you actually want one row per original row still;
    call missing(r[_n_]); *clear it out;
  end;
  drop forecast;
run;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM