我有以下数据集。
ID var1 var2 var3
1 100 200
1 150 300
2 120
2 100 150 200
3 200 150
3 250 300
我想有一个新的数据集,每个变量组只有最后一个非空白记录。
id var1 var2 var3
1 150 200 300
2 100 150 200
3 250 300 150
持续。选择最后一条记录,但我需要选择最后一条非空记录
看起来你想要每个非关键变量的最后一个非缺失值。所以你可以让UPDATE
声明为你工作。通常,对于更新操作,您可以将事务应用于主数据集。但是对于您的应用程序,您可以使用OBS=0
数据集选项使您当前的数据集同时作为主数据库和事务处理。
data want ;
update have(obs=0) have ;
by id;
run;
里卡多:
在每个组中,有多种方法可以选择每列的最后一个非缺失值。这有三种方式。我不会说一个是最好的方法,每种方法都有它的优点,具体取决于具体的数据集,编码器的舒适性和长期可维护性。
也许最简单的编码方法是这样的:
UPDATE
语句将每个类似命名的变量替换为非缺失值。例:
data want_base_table(label="One row per id, original columns");
set have;
by id;
if first.id;
run;
* use have as a transaction data set in the update statement;
data want_by_update;
update want_base_table have;
by id;
run;
其他人将涉及阵列和第一。最后。 BY
组的标志变量。此示例显示了一个DOW
循环,它跟踪非缺失值,然后将它们用于每个ID
的输出:
data want_dow;
do until (last.id);
set have;
by id;
array myvar var1-var3 ;
array myhas has1-has3 ;
do _i = 1 to dim(myvar);
if not missing (myvar(_i)) then
myhas(_i) = myvar(_i);
end;
end;
do _i = 1 to dim(myhas);
myvar(_i) = myhas(_i);
end;
output;
drop _i has1-has3;
run;
当在DOW
块内部存在SET
语句并且循环终止由DO; END;
标志变量触发时,循环通常被称为last.
循环。类似的非DOW方法(未示出)将使用隐式循环和first.
来初始化跟踪数组,并使用last.
将值(在组内跟踪)复制到用于输出的列中。
data want_by_column_slices;
merge
have (keep=id var1 where=(var1 ne .))
have (keep=id var2 where=(var2 ne .))
have (keep=id var3 where=(var3 ne .))
;
by id;
if last.id;
run;