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

Macros SAS:在数据步中将宏变量用作数字,macros,sas,datastep,Macros,Sas,Datastep,我正在修改我编写的一些SAS代码,发现了一段我希望更有效地执行的代码。我有一个称为“预测”的时间序列数据集,它只包含日期和给定日期的“预测”变量 我写了一个简单的代码块来获取这个变量,基本上把它分割成一系列变量,每个变量代表一个日期: 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

我正在修改我编写的一些SAS代码,发现了一段我希望更有效地执行的代码。我有一个称为“预测”的时间序列数据集,它只包含日期和给定日期的“预测”变量

我写了一个简单的代码块来获取这个变量,基本上把它分割成一系列变量,每个变量代表一个日期:

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;
然而,这段代码的'r(241)'部分真的让我很恼火。我已经有了一个宏变量,它对应于我需要执行此操作的次数(称为“n”),我更愿意直接将其插入数组声明中,类似于:

array r(&n)
等等

然而,宏变量显然被视为文本,因此即使我设法将宏变量导入到数据步骤中,变量r(&n)也不起作用,因为它不会将“n”读取为数字。除了将整个数据步骤包装到一个更广泛的宏中之外,如何将“n”拉入数据步骤,然后将其转换为数字,以便此操作正常工作?

语句:

array r(&n) ;
假设宏变量已定义且具有整数值,则应该可以。请说明您如何尝试使用它(以及任何失败的日志消息)。您不需要“将宏变量导入数据步骤”。宏变量是文本,因为它们的主要任务是解析为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
声明:

array r(&n) ;
假设宏变量已定义且具有整数值,则应该可以。请说明您如何尝试使用它(以及任何失败的日志消息)。您不需要“将宏变量导入数据步骤”。宏变量是文本,因为它们的主要任务是解析为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

作为建议,你不需要这样做<代码>过程转置就是为了这个目的而存在的。然后,您甚至不必知道有多少变量/行

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;
如果实际上不需要243行,而只需要一行,则转储
by
id
语句

即使您希望在数据步骤中执行此操作,您也可以通过将
集合
放入循环中来更快地执行此操作(现在您正在检查241*241次,您只需要241次…)。这里我使用自动删除的变量
\u n\u
来迭代循环

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;

作为建议,你不需要这样做<代码>过程转置就是为了这个目的而存在的。然后,您甚至不必知道有多少变量/行

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;
如果实际上不需要243行,而只需要一行,则转储
by
id
语句

即使您希望在数据步骤中执行此操作,您也可以通过将
集合
放入循环中来更快地执行此操作(现在您正在检查241*241次,您只需要241次…)。这里我使用自动删除的变量
\u n\u
来迭代循环

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;

奇怪的是,我想我什么都试过了,除了just&n,使用各种过于复杂的电话等等。使用&n确实很好,很抱歉在那里浪费了你的时间。奇怪的是,我想我什么都试过了,除了just&n,使用各种过于复杂的电话等等。使用&n确实很好,很抱歉在这里浪费您的时间。请注意,我在示例中使用了243,而不是241,因此请将其调整为正确的值。非常酷,我的数据集实际上比241个变量大很多,因此我将解决这个问题并实现它以节省时间。我还注意到,根据您这样做的目的,可能有更好的方法可以做到这一点-例如,如果您正在创建对角矩阵,
PROC IML
是这样做的地方,一些更高级的回归/etc。类型分析例程也可以为您做到这一点。感谢您的帮助,我需要更多地了解如何使用“By”。目前我处于SAS级别,我可以做我需要的大部分事情,但有时感觉我只是在用锤子砸东西,以牺牲效率和良好的代码为代价。所以所有的建议都是值得赞赏的。注意,我在我的示例中使用了243,而不是241,所以请将其调整为正确的值。非常酷,我的数据集实际上比241个变量大很多,所以我将找出这个问题并实施它,以节省时间。我还注意到,根据您这样做的目的,可能有更好的方法可以做到这一点-例如,如果您正在创建对角矩阵,
PROC IML
是这样做的地方,一些更高级的回归/etc。类型分析例程也可以为您做到这一点。感谢您的帮助,我需要更多地了解如何使用“By”。目前我处于SAS级别,我可以做我需要的大部分事情,但有时感觉我只是在用锤子砸东西,以牺牲效率和良好的代码为代价。因此,所有建议都受到赞赏。