我有一个名为have
的数据集,其中一个条目包含多个变量,如下所示:
message reference time qty price
x 101 35000 100 .
上述数据集每次都在message
可以=“A”的循环中发生变化。如果message
=“X”,那么这意味着从MASTER集中删除100个数量,其中reference
数字等于MASTER数据库中的reference
数字。 price
=。是因为它已经在reference
= 101下的MASTER数据库中。 MASTER数据库以某种价格汇总所有可用订单和可用数量。如果在下一个循环message
=“A”中,那么have
数据集将如下所示:
消息参考时间数量价格 A 102 35010 150 500
那么这意味着要向MASTER数据库添加一个新的reference
号码。换句话说,到append
到MASTER的行。
我的循环中有以下代码,当有message
X时更新MASTER数据库中的数量:
data b.master;
modify b.master have(where=(message="X")) updatemode=nomissingcheck;
by order_reference_number;
if _iorc_ = %sysrc(_SOK) then do;
replace;
end;
else if _iorc_ = %sysrc(_DSENMR) then do;
output;
_error_ = 0;
end;
else if _iorc_ = %sysrc(_DSEMTR) then do;
_error_ = 0;
end;
else if _iorc_ = %sysrc(_DSENOM) then do;
_error_ = 0;
end;
run;
我使用replace
更新数量。但是因为我的price
=。当message
为X时,上述代码会设置price
='。'通过reference
语句在MASTER中replace
= 101 ...我不想要。因此,我更愿意删除message
数据集中的价格列have
= X.但是我不想在message
= A时删除列价,因为我使用此代码
proc append base=MASTER data=have(where=(msg_type="A")) force;
run;
因此,我的代码价格为Modify
声明:
data have(drop=price_alt);
set have; if message="X" then do;
output;end;
else do; /*I WANT TO MAKE NO CHANGE*/
end;run;
但它没有做我想要的。如果消息不等于X,那么我不想删除列。如果它等于X,我想删除列。如何调整上面的代码才能使其正常工作?
答案 0 :(得分:3)
试试这个:
data outX(drop=price_alt) outNoX;
set have;
if message = "X" then
output outX;
else
output outNoX;
run;
正如@sasfrog在评论中所说的那样,一个表要么有列,要么没有。如果你想要MESSAGE =“X”的子集,那么你可以使用这样的东西来创建2个数据集。
答案 1 :(得分:3)
诚实地说这是一个奇怪的要求,这样就会提出一个问题,即你所做的是最好的做法。但是,本着回答这个问题的精神......
DomPazz的答案提供了将数据拆分为两个可能的集合的选项,但如果您希望代码中的代码始终引用特定的数据集,则会产生其自身的复杂性。
在一个数据步骤中,您也不能告诉SAS输出到“相同”数据集,其中一个实例具有列而一个实例没有。因此,您希望代码本身是动态的,因此存在的数据步骤可以是删除列的数据步骤,也可以是不删除列的数据步骤,具体取决于message = x。对此动态代码的回答与SAS中的许多内容一样,解决了宏的创造性使用问题。它看起来像这样:
/* Just making your input data set */
data have;
message='x';
time=35000;
qty=1000;
price=10.05;
price_alt=10.6;
run;
/* Writing the macro */
%macro solution;
%local id rc1 rc2;
%let id=%sysfunc(open(work.have));
%syscall set(id);
%let rc1=%sysfunc(fetchobs(&id, 1));
%let rc2=%sysfunc(close(&id));
%IF &message=x %THEN %DO;
data have(drop=price_alt);
set have;
run;
%END;
%ELSE %DO;
data have;
set have;
run;
%END;
%mend solution;
/* Running the macro */
%solution;