在SAS中查找字符串,并在宏变量中捕获变量的变量名称和位置

时间:2015-12-16 20:26:16

标签: sas

我有非常多的数据集,这些数据集的格式不一致 - 我试图将它们读入SAS并对其进行规范化。

这里的基本需求是找到一个关键列'包含某个字符串 - 从那里我知道如何处理该列左侧和右侧的所有变量。

' GREP'来自sas网站(http://support.sas.com/kb/33/078.html)的宏似乎可以解决这个问题,但我需要帮助以下列方式调整代码:
1 - 我只需要一次搜索一个数据集,已经在' work'库。
2 - 我需要捕获打印到此宏末尾的日志的变量名称(及其位置编号)。这似乎很容易,但它只返回数据集中的最后一列,而不是最后打印到日志的(正确)列。

以下当前代码:

%macro grep(librf,string);  /* parameters are unquoted, libref name, search string */
%let librf = %upcase(&librf);
  proc sql noprint;
    select left(put(count(*),8.)) into :numds
    from dictionary.tables
    where libname="&librf";

    select memname into :ds1 - :ds&numds
    from dictionary.tables
    where libname="&librf";

  %do i=1 %to &numds;
    proc sql noprint;
    select left(put(count(*),8.)) into :numvars
    from dictionary.columns
    where libname="&librf" and memname="&&ds&i" and type='char';

    /* create list of variable names and store in a macro variable */

    %if &numvars > 0 %then %do;
      select name into :var1 - :var&numvars 
      from dictionary.columns
      where libname="&librf" and memname="&&ds&i" and type='char';
      quit;

      data _null_;
        set &&ds&i;
          %do j=1 %to &numvars;
            if &&var&j = "&string" then
            put "String &string found in dataset &librf..&&ds&i for variable &&var&j";
          %end;
        run;
    %end;
  %end; 
%mend;
%grep(work,Source Location);  

日志返回:"在变量C"的数据集WORK.RAW_IMPORT中找到的字符串源位置。 (第三),这是正确的。

我只需要可用的宏变量等于" C"和" 3"在末尾。这个宏将是一个更大的宏(或它的前奏)的一部分,所以两个宏变量需要重置我运行它的每个数据集。感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

请在下面找到修改,基本上我所做的就是为数据集名称和变量名创建全局宏变量,它将作为输入提供,以使用VARNUM函数获取变量位置,如下所示(由****标识的更改) )

%macro grep(librf,string);  
  %let librf = %upcase(&librf);  

  proc sql noprint;
    select left(put(count(*),8.)) into :numds
    from dictionary.tables
    where libname="&librf";

    select memname into :ds1 - :ds&numds
    from dictionary.tables
    where libname="&librf";

    %do i=1 %to &numds;
       proc sql noprint;
         select left(put(count(*),8.)) into :numvars
         from dictionary.columns
         where libname="&librf" and memname="&&ds&i" and type='char';

         /* create list of variable names and store in a macro variable */

         %if &numvars > 0 %then %do;
          select name into :var1 - :var&numvars 
          from dictionary.columns
          where libname="&librf" and memname="&&ds&i" and type='char';
          quit;

          %global var_pos var_nm var_ds;

          data _null_;
            set &&ds&i;
            %do j=1 %to &numvars;

            **** ADDED NEW CODE HERE ****;
            if &&var&j = "&string" then do; /* IF-DO nesting */;
              call symputx("var_nm","&&var&j"); /*Global Macro variable for Variable Name */
              call symputx("var_ds","&&ds&i"); /*Global Macro variable for Dataset Name */
             put "String &string found in dataset &librf..&&ds&i for variable &&var&j";
          %end;
        run;  

        **** ADDED NEW CODE HERE ****;
        %let dsid=%sysfunc(open(&var_ds,i)); /* Open Data set */
        %let var_pos=%sysfunc(varnum(&dsid,&var_nm));  /* Variable Position */
        %let rc=%sysfunc(close(&dsid)); /* Close Data set */;

      %end;
   %end; 
%mend;

%grep(work,Source Location); 

%put &=var_nm &=var_ds &=var_pos;