SAS编程-利用宏变量批量构建SAS语句

欢迎关注,SAS茶谈!

前面文章SAS编程-小知识:import过程步的Guessingrows选项介绍了导入txt文本的遇到的问题,由于“NA”字符的存在,之前一些本是数值型的变量导入SAS数据集后,变成了字符型变量。

为方便后续的编程,需要将其转化为字符变量,“NA”的记录直接赋值为空值。这个在RawData处理中,还是比较常见的。

对于单个变量处理如下:

data test;
  set test0(rename=(var1 = var1_));
  if var1_ ne "NA" then var1 = input(strip(var1_), best.);
  else var1 = .;
run;

如果需要转化的变量较少,依次手动写程序是没什么问题的。可一旦变量数目上去,依次硬写无疑是一件低效的事情。这时候,考虑利用宏变量批量构建SAS语句进行实现

这篇文章介绍利用宏变量批量构建SAS语句,内容涉及将一列变量所有值保存到宏变量中

1. 实现思路

批量构建的第一步是,明确完成状态下的程序是怎么样的。不同的实现路径,批量构建的内容也不同。

以上面单变量处理为例,rename语句的实现比较单一,直接增加变量赋值等式就好。而if语句的处理就可以有多种,例如,有多少个变量,就对应有多少个if语句;例如,通过宏循环进行处理;例如,通过数组循环进行处理

这里以数组循环举例,演示数据集为SASHelp.Class。目标是每个数值型变量+2并转化为字符型变量,并且变量的名称不变

SASHELP.CLASS

根据目标,思考下程序的大体逻辑:

  1. 为避免变量属性冲突,需要对原变量名称Rename;
  2. 新建数组需要获取原数值变量名称,以及对应的Rename语句;
  3. 数组循环需要考虑到数值变量的数目。

2. 变量信息的获取

获取数据集的数值变量名称,方便后续构建对应的SAS语句:

data column;
  set sashelp.vcolumn;                              *;
  where libname = "SASHELP" and memname = "CLASS" and type = "num";
  
  length name_r rename $50;
  name_r = strip(name)||"_";
  rename = strip(name) || " = " || strip(name_r);

  keep name: rename ;
run;

输出结果如下:

3. 利用宏变量构建SAS语句

最后实现的目标程序如下:

data class;
  set sashelp.class(rename=(Age = Age_ Height = Height_  Weight = Weight_));
  
  array num{3} Age_ Height_ Weight_;
  array char{3}  $ 8 Age Height Weight;

  do i = 1 to 3;
    char{i} = strip(put(num{i} + 2, best.));
  end;

  drop Age_ Height_ Weight_ i;
run;

结合数据集以及目标程序,我们需要将列内容拼接并保存到宏变量中。生成宏变量可以使用Data步和Proc SQL,下面分别以这两种方法进行实现。

3.1 Data步生成宏变量

在Data步中,可以使用symputx将变量值赋值到宏变量。而整理内容的拼接整合,可以通过Retain变量进行实现。内容拼接完毕后,在数据的最后一行,将值赋值给宏变量。

data tmp;
  set column end=eof;
  length name_m name_r_m rename_m $1000;
  retain name_m name_r_m rename_m " ";
  
  name_m = strip(name_m )||" "||strip(name);
  name_r_m  = strip(name_r_m  )||" "||strip(name_r);
  rename_m = strip(rename_m )||" "||strip(rename);

  if eof then do;
    call symputx("var_char", strip(name_m) );
    call symputx("var_num", strip(name_r_m) );
    call symputx("var_rename", strip(rename_m ) );
    call symputx("n", strip(put(_n_, best.)) );
  end;
run;

%put var_char = &var_char.;
%put var_num= &var_num.;
%put var_rename= &var_rename.;
%put n= &n.;

数据集输出如下:

宏变量输出如下:

宏变量设置完毕后,目标程序中的特定SAS语句就可以使用宏变量替代。

data class;
  set sashelp.class(rename=(&var_rename.));
  
  array num{&n.} &var_num.;
  array char{&n.}  $ 8 &var_char.;

  do i = 1 to &n.;
    char{i} = strip(put(num{i} + 2, best.));
  end;

  drop &var_num. i;
run;

运行之后,最后的数据集处理如下:

这样处理既实现了既定的效果,同时,也避免了依次单独处理每个变量。在大批量的变量处理中,这是非常高效的。

3.2 SQL过程步生成宏变量

SQL过程步通过into :子句生成宏变量,具体方法在SAS编程:Proc SQL生成宏变量时INTO子句的使用 中有过介绍,我们需要使用第3种形式:

  1. into : macro-variable(指定一个或多个宏变量)
  2. into : macro-variable-1 − : macro-variable-n (指定一个宏变量序列)
  3. into : macro-variable SEPARATED BY 'characters ' 指定一个宏变量来保存一列的所有值

具体程序如下:

proc sql noprint;
  select name into: var_char separated by " "  from column;
  select name_r into: var_num separated by " "  from column;
  select rename into: var_rename separated by " "  from column;
  select count(*) into: n from column;
quit;

%put var_char = &var_char.;
%put var_num= &var_num.;
%put var_rename= &var_rename.;
%put n= &n.;

宏变量输出结果如下:

与Data步相比,SQL过程步显得更简洁,不需要对行记录进行拼接处理。后续,调用的宏变量的代码同Data步,这里不再演示。

总结

编程中遇到大量同类型的处理需求时,需要考虑批量处理。批量处理的方式有很多,本篇文章使用的方法是将需要的程序元素保存到宏变量中。

生成宏变量可以通过Data步中的call symputx语句,也可以通过SQL中的into :子句。本篇需要将一列变量的所有值保存到宏变量中,通过Data步实现要利用retain语句进行拼接。

感谢阅读, 欢迎关注:SAS茶谈!
若有疑问,欢迎评论交流!

你可能感兴趣的:(SAS编程-利用宏变量批量构建SAS语句)