以下继承的简化代码旨在使用组中不缺少条目的值替换列的缺失值:
DATA WORK.TOYDATA;
INPUT Category $ PRICE;
DATALINES;
Cat1 2
Cat1 .
Cat1 .
Cat2 .
Cat2 3
Cat2 .
;
DATA WORK.OUTTOYDATA;
SET WORK.TOYDATA;
BY Category ;
RETAIN _PRICE;
IF FIRST.Category THEN _PRICE=PRICE;
IF NOT MISSING(PRICE) THEN _PRICE=PRICE;
ELSE PRICE=_PRICE;
DROP _PRICE;
RUN;
不幸的是,如果组中的第一个条目丢失,这将不起作用。怎么能修好?
答案 0 :(得分:2)
当SAS逐行遍历数据集时,如果缺少第一个值,则没有值可以替换。 您可以按类别和价格DESCENDING对数据进行排序以避免这种情况。
proc sort data= WORK.TOYDATA; by Category DESCENDING PRICE; run;
或者如果按类别只有一个NON-missing值,则可以使用sql join,例如
proc sql;
create table WORK.OUTTOYDATA as
select a.Category, coalesce(a.PRICE, b.PRICE) as PRICE
from WORK.TOYDATA a
left join (select distinct Category, PRICE
from WORK.TOYDATA
where PRICE ne .
) b
on a.Category eq b.Category
;
quit;
答案 1 :(得分:1)
正如@Jetzler所指出的,最简单的方法就是对数据进行排序。但是,如果您有多个缺少值的列,那么您需要进行多种排序,这样做效率不高。
进行连接的另一个选择是proc stdize
,它可以用一个简单的度量(平均值,中位数,总和等)来替换缺失值。在您的示例中,默认方法就足够了,您只需添加reponly
选项,该选项仅替换缺失值并且不会标准化数据。
DATA WORK.TOYDATA;
INPUT Category $ PRICE;
DATALINES;
Cat1 2
Cat1 .
Cat1 .
Cat2 .
Cat2 3
Cat2 .
;
run;
proc stdize data=TOYDATA out=want reponly;
by category;
var price;
run;