正确使用宏在 sas 中子集数据并将它们附加到文件

subset data in sas using macro properly and append them to a file

我有一些数据集,我根据一些生物学文献,按照一些方法写了一些代码来清洗,然后我想把它分成白天和晚上(因为他们必须分开分析)。它有效,但现在我需要对整套文件执行此操作,这对于我想要一个一个处理的许多文件来说是一种方式。所以我现在正在尝试编写一个宏来为我将它分成白天和黑夜..

我的数据是这样的

   Hour         var1      var2      var3
     1            123       90       100
     2            122       99       108
     ...........
     4            156       80       120
     4            156       80       145
     4            143       82       132

基本上晚上每小时有 1 个 obs 第 3 天。我也有很多天。

每个数据集被命名为 STUDYIDID#_first 或 STUDYID_ID#_last。我想为每个数据集生成四个数据集。 因此 MYID111_first 将创建:MYID111_first_day_var1、MYID111_first_day_var2、MYID111_first_night_var1 和 MYID111_first_night_var2。

然后我想将它们附加到 4 个数据集中: MYID_A_first_day_var1、MYID_A_first_day_var2、MYID_A_first_night_var1 和 MYID_A_first_night_var2。

到目前为止我的代码:

   %macro datacut(libname,worklib=work, grp = _A ,time1 = _night , time2 = _day type1 = _var1 , type2 = _var2);


   %local num i;
      proc datasets library=&libname memtype=data nodetails;
      contents out=&worklib..temp1(keep=memname) data=_all_ noprint;
    run;

   data _null_;
      set &worklib..temp1 end=final;
      by memname notsorted;
      if last.memname;
      n+1;
      call symput('ds'||left(put(n,8.)),trim(memname));

      if final then call symput('num',put(n,8.));

   run;

   %do i=1 %to #

   /* do the artifact removing method */
   DATA &libname..&&ds&i; 
   SET &libname..&&ds&i; 
       PT_ID = '&ds&i' ;
       IF var1< 60 OR var1> 230 then delete; 
       IF var2< 30 OR var2> 230 THEN delete; 
       IF var3< 60OR var3 > 135 THEN DELETE; 
       IF var2 > var1 then delete; 
   run;
   /* get just the night values */
   PROC SQL;
    CREATE TABLE &libname..&&ds&i&time1 as
        SELECT * 
        FROM &libname..&&ds&i 
        WHERE Hour BETWEEN 0 and 6 OR Hour BETWEEN 22 and 24
        order by systolic
    ; 
    QUIT;
    /* trim off the proper number of observations for variable 1 */
    DATA &libname..&&ds&i&time1&type1; 
    SET &libname..&&ds&i&time1  end=eof; 
        IF _N_ =1 then delete;  
        if eof then delete; 
    run;
   PROC append base= &libname..&&ds&time1&type1 
   data= &libname..&&ds&i&time1;
   run;

QUIT;


   %end;
%mend datacut;


%datacut(work)

现在初始数据步可以正常工作,但后面的数据步不会按计划重命名数据。我得到了一堆名为 Ds10_night_var1 的数据集,其中包含错误的字段名称(memtype、nodetails、data)

我收到警告:

WARNING: Apparent symbolic reference DS1_NIGHT not resolved.
NOTE: Line generated by the macro variable "TIME1".
1      work.&ds1_night
            -
            22
            200
ERROR 22-322: Expecting a name.

ERROR 200-322: The symbol is not recognized and will be ignored.

NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

WARNING: Apparent symbolic reference DS1_NIGHT_SYS not resolved.


22: LINE and COLUMN cannot be determined.
NOTE 242-205: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and
              COLUMN where the error has occurred.
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, /, ;,
              _DATA_, _LAST_, _NULL_.
201: LINE and COLUMN cannot be determined.
NOTE: NOSPOOL is on. Rerunning with OPTION SPOOL might allow recovery of the LINE and COLUMN
      where the error has occurred.
ERROR 201-322: The option is not recognized and will be ignored.

所以我想要我的文件和数据集的正确名称以实际包含数据,我不明白为什么他们不这样做。

如您所知,您将宏变量写成 & 后跟它的名称,可以选择后跟 .。有了这个 . 你可以显式地结束宏变量引用,所以你可以使用宏变量作为前缀,就像

%let prefix = fore;
Aspect = &prefix.Ground;

计算结果为 Aspect = foreGround;。这就是为什么

%let myLib = abc;
%let mymember = xyz;
data &myLib.&myMember;

是一个错误,因为它的计算结果为 data abcxyz;,您必须写成

data &myLib..&myMember; 
** or as I prefer **;
data &myLib..&myMember.;

得到data abc.xyz;.

对于您需要宏变量来创建宏变量名称的情况,SAS 允许编写双符号 &&,其计算结果为单个 & 并继续计算,直到所有符号都被消耗。所以假设

%let i = 1;
%let ds1 = myData;
%let time = _nigth;

SAS 是这样计算的 &&ds&i&time1 :

  • &&ds&i&time1
  • &ds1_night
  • 错误,因为未定义宏变量 ds1_night

SAS 是这样计算的 &&ds&i..&time1. :

  • &&ds&i..&time1.
  • &ds1._night
  • myData_night