我有一些数据集,我根据一些生物学文献中的一些方法编写了一些代码来清理,然后我想把它分成白天和黑夜(因为它们必须单独分析)。它工作但现在我需要为完整的设置这样做,这是许多文件的方式让我想要逐个处理。所以我现在正在尝试编写一个宏来为我分割成日夜。
我的数据看起来像是
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个障碍物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)
现在初始datastep正常工作,但后者不按计划重命名数据。我得到了一堆名为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.
所以我希望我的文件和我的数据集的正确名称实际上有数据我不知道他们为什么不这样做。
答案 0 :(得分:1)
如您所知,您将宏变量写为&
,后跟其名称,后跟.
。使用此.
,您可以显式结束宏变量引用,因此您可以使用宏变量作为前缀,例如
%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