将宏变量设置为 table 中的值
Setting Macro Variable equal to value in table
我有一个 1 行 4 列的 table。我想创建 4 个以每列命名的宏变量,其中值设置为第 1 行中的值。
如果这是 R,我可以直接访问这些值:
newvar1=tablename[1,1]
newvar2=tablename[1,2]...
我是否可以从 table 中获取 select 值并将宏变量设置为等于该值?
所以像这样:
%macrovar1=tablename[1,1]...
除了显然等号右边是 R 代码而不是 SAS。
谢谢
方法有多种,但最简单的是:
data _null_;
set have;
if _n_=1 then do;
call symputx('macrovar1',var1);
*more of these;
end;
stop;
run;
打开数据集,然后如果在第一行(_n_
是数据步循环的迭代,在大多数情况下是第一行),使用call symputx将其值赋给a宏变量.
我要注意,你应该记住SAS宏变量不是数据变量,没有数据类型(总是文本),通常不用于存储以您在 R 中使用向量的方式获取数据。
你可以使用 proc sql 来做:
proc sql noprint inobs=1;
select name into :my_val from sashelp.class;
quit;
%put &my_val;
或者您可以像这样从数据步骤中使用 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;
以上宏是找到的 %ds2list 宏的缩写版本 here。
我有一个 1 行 4 列的 table。我想创建 4 个以每列命名的宏变量,其中值设置为第 1 行中的值。
如果这是 R,我可以直接访问这些值:
newvar1=tablename[1,1]
newvar2=tablename[1,2]...
我是否可以从 table 中获取 select 值并将宏变量设置为等于该值?
所以像这样:
%macrovar1=tablename[1,1]...
除了显然等号右边是 R 代码而不是 SAS。
谢谢
方法有多种,但最简单的是:
data _null_;
set have;
if _n_=1 then do;
call symputx('macrovar1',var1);
*more of these;
end;
stop;
run;
打开数据集,然后如果在第一行(_n_
是数据步循环的迭代,在大多数情况下是第一行),使用call symputx将其值赋给a宏变量.
我要注意,你应该记住SAS宏变量不是数据变量,没有数据类型(总是文本),通常不用于存储以您在 R 中使用向量的方式获取数据。
你可以使用 proc sql 来做:
proc sql noprint inobs=1;
select name into :my_val from sashelp.class;
quit;
%put &my_val;
或者您可以像这样从数据步骤中使用 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;
以上宏是找到的 %ds2list 宏的缩写版本 here。