从数据集中的字符串执行SAS代码

时间:2013-07-30 09:49:42

标签: sas sas-macro

是否可以读取(并执行)存储在SAS数据集中的字符串中的SAS代码。

例如,数据集“CODE”包含一个字符串变量,其中包含

"IF TOTAL_SALES GE 20000 AND TYPE IN ('A', 'B', 'C') THEN VAR1 = 'Y' ;"

我能做点什么吗?

data sales ;
set sales ;
/* run the if statement above */
run ;

使用SAS 9.2

3 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点,因为有很多方法可以构建宏变量。通常最有用的三个:

proc sql select into

这允许您立即创建多行代码,并且可能是用于此目的的最常用工具。它可以直接创建代码行,也可以更有用地创建宏调用。例如,假设你想要运行:

data want;
set have;
x = sum(a,b,c);
run;

但是x,a,b,c都是在另一个数据集中定义的。此外,你有3个这样的变量。

data callset;
input var1 $ var2 $ var3 $ var4 $;
datalines;
x a b c
y d e f
z b e c
;;;;
run;

你可以用这种方式构建它:

proc sql;
select cats(x,"=sum(",a,",",b,",",c,");") into :calllist
 separated by ' '
 from callset;
quit;

data want;
set have;
&calllist.
run;

但是,构建宏可能更容易:

%macro sum(var1,var2,var3,var4);
&var1. = sum(&var2.,&var3.,&var4.);
%mend sum;

然后你的PROC SQL更容易一点(在这种情况下并不是真的,但通常这有助于在更复杂的代码中实现可读性):

proc sql;
select cats('%sum(',catx(',',x,a,b,c),')') into :calllist
 separated by ' '
 from callset;
quit;

然后以同样的方式使用它。

这里的限制:除了PROC SQL允许你做什么之外你不能修改字符串(这是强大的,但不是datastep代码,如果你需要使用像first.var这样的东西你必须这样做在proc sql之前的单独步骤)。您在宏变量中总共有大约20k个字符的限制。

顺便说一句,separated by很重要;没有它你只能创建一行代码(只有最后一行将被放入宏变量)。即使你真的不希望它被任何东西分开,你仍然需要用''分隔才能生成列表。

%包含文件

include文件方法是proc sql方法和call execute的混合体。它是在数据步骤中构建的,并且没有超出操作系统文件大小限制的长度限制。然而,它有点混乱(因为创建了一个临时文件)并且具有包含文件的常规限制,例如不包含数据。

您可以通过这种方式构建它(使用以前的数据集):

filename toincl temp; *create temporary fileref;
data _null_;
set callset;
file toincl;
callstr = cats('%sum(',catx(',',x,a,b,c),')');
put callstr $;
run;

data want;
set have;
%include toincl;
run;

它解决了PROC SQL长度限制,但具有包含文件的常规限制(有关详细信息,请参阅the documentation)。

致电执行

这用于在数据步骤之后立即以交互方式执行一行代码。它很方便,因为它允许您比其他方法更灵活地构建代码,但它具有显着的时序限制。

data _null_;
set callset; *this is not the main data set, but the control file with SAS code;
call execute('data want; set have;');
callstr=cats('%sum(',catx(',',x,a,b,c),')');
call execute(callstr);
call execute('run;');
run;

人们通常遇到麻烦的主要限制是宏变量计时。在CALL EXECUTE步骤中定义宏变量时,在同一个CALL EXECUTE步骤中无法使用它。因此,如果您的代码包含要创建的代码然后使用宏变量,它将无法正常运行;你需要使用其他方法之一。如果您使用此方法,我强烈建议您先阅读一些关于CALL EXECUTE的论文,例如this onethis one

答案 1 :(得分:2)

有两种方法:

  1. 在数据步骤中使用call symput将其置于宏变量中。然后,将宏变量放在要执行代码的位置。 (考虑到SAS解释并执行什么时的注意事项)
  2. 在数据步骤中使用call execute。请注意,所有输入到执行调用中的代码都会在数据步骤中累积,然后在数据步骤之后立即解释并执行
  3. 对于呼叫执行,请参阅:http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000543697.htm

答案 2 :(得分:0)

在读入sales数据之前,您希望在创建包含SAS代码的宏变量之前使用调用symput函数。以下是一些示例代码:

* _null_ means there is no output dataset;
data _null_;
    set code;

    * assuming char variable containing the SAS code is called 'code_string';
    * if only certain rows contain the correct code_string values;
    * then you could use an if statement to assign &my_code as desired;
    call symput('my_code', code_string);
run;

data sales;
    set sales;

    * now access the value of the macro variable created with call symputx above;
    &my_code
run;

如果包含SAS代码字符串的char变量的code数据集只是一行(或者可以限制为带有where语句的单行),那么您可以使用{ {1}}以获得与上述proc sql数据步骤相同的结果:

_null_