将宏变量设置为等于表中的值

时间:2015-04-15 16:41:59

标签: sas

我有一个包含一行和四列的表。我想创建在每列之后命名的4个宏变量,其中值设置为1行中的值。

如果是R,我可以直接使用以下内容访问这些值:

newvar1=tablename[1,1]
newvar2=tablename[1,2]...

我是否还要从表中选择值并设置等于该值的宏变量?

类似于:

%macrovar1=tablename[1,1]...

除了显然,等号的右侧是R代码而不是SAS。

由于

2 个答案:

答案 0 :(得分:4)

你可以使用proc sql这样做:

proc sql noprint inobs=1;
  select name into :my_val from sashelp.class;
quit;
%put &my_val;

或者您可以使用datastep中的call symput,如下所示:

data _null_;
  set sashelp.class(obs=1);
  call symput('my_val',name);
run;

对于更灵活的东西,我们使用一个实用程序宏,它允许我们从代码中的任何位置检查值。我稍微修改了它以满足您的要求,但用法如下:

%let my_val = %get_val(iDs=sashelp.class, iField=name);

您也可以在proc或datastep中间使用它,如下所示:

data _null_;
  my_value = "%get_val(iDs=sashelp.class, iField=name)";
run;

甚至:

proc sql noprint;
  create table want as
  select * from sashelp.class
  where name = "%get_val(iDs=sashelp.class, iField=name)"
  ;
quit;

这是宏定义:

%macro get_val(iDs=, iField=);
  %local dsid pos rc result cnt value;

  %let result=;
  %let cnt=0;

  /*
  ** ENSURE ALL THE REQUIRED PARAMETERS WERE PASSED IN.
  */
  %if "&iDs" ne "" and "&iField" ne "" %then %do;

    %let dsid=%sysfunc(open(&iDs,i));
    %if &dsid %then %do;

      %let pos=%sysfunc(varnum(&dsid,&iField));
      %if &pos %then %do;

        %let rc=%sysfunc(fetch(&dsid));

        %if "%sysfunc(vartype(&dsid,&pos))" = "C" %then %do;
          %let value = %qsysfunc(getvarc(&dsid,&pos));
          %if "%trim(&value)" ne "" %then %do;
            %let value = %qtrim(&value);
          %end;
        %end;
        %else %do;
          %let value = %sysfunc(getvarn(&dsid,&pos));
        %end;
        &value

      %end;
      %else %do;
        %put ERROR: MACRO.GET_VAL.SAS: FIELD &iField NOT FOUND IN DATASET %upcase(&iDs).;
      %end;
    %end;
    %else %do;
      %put ERROR: MACRO.GET_VAL.SAS: DATASET %upcase(&iDs) COULD NOT BE OPENED.;
    %end;

    %let rc=%sysfunc(close(&dsid));

  %end;
  %else %do;
    %put ERROR: MACRO.GET_VAL.SAS: YOU MUST SPECIFY BOTH THE IDS AND IFIELD PARAMETERS TO CALL THIS MACRO.;
  %end;

%mend;

上面的宏是找到{%{3}}的%ds2list宏的缩写版本。

答案 1 :(得分:3)

有几种方法,但最简单的是:

data _null_;
  set have;
  if _n_=1 then do;
    call symputx('macrovar1',var1);
   *more of these;
  end;
  stop;
run;

打开数据集,然后如果在第一行(_n_是数据步骤循环的迭代,在大多数情况下是第一行),使用call symputx将其值赋给宏变量

我会注意到你应该记住,SAS宏变量不是数据变量,没有数据类型(总是文本),通常不会像你那样用来存储数据在R.使用向量