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

在SAS中查找字符串,并在宏变量中捕获变量的名称和位置,sas,Sas,我有很多数据集的格式不一致——我正在尝试将它们读入SAS并进行规范化 这里的基本需求是找到一个包含特定字符串的“键列”——从那里我知道如何处理该列左右的所有变量 sas网站()中的“GREP”宏似乎可以处理这个问题,但我需要以下方面的帮助来调整代码: 1-我一次只需要搜索一个数据集,已经在“工作”库中了。 2-我需要捕获在该宏末尾打印到日志中的变量的名称(及其位置号)。这看起来很简单,但它只返回数据集中的最后一列,而不是最后打印到日志中的(正确)列 当前代码如下: %macro grep(lib

我有很多数据集的格式不一致——我正在尝试将它们读入SAS并进行规范化

这里的基本需求是找到一个包含特定字符串的“键列”——从那里我知道如何处理该列左右的所有变量

sas网站()中的“GREP”宏似乎可以处理这个问题,但我需要以下方面的帮助来调整代码:
1-我一次只需要搜索一个数据集,已经在“工作”库中了。
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的dataset WORK.RAW_IMPORT中找到的字符串源位置”(第三个),这是正确的


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

请查找下面的修改,基本上我所做的是为dataset name和variable name创建全局宏变量,该变量将作为输入,使用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;