SAS-跨行复制多个观察结果
我的数据结构如下所示:SAS-跨行复制多个观察结果,sas,rows,replicate,Sas,Rows,Replicate,我的数据结构如下所示: DATA have ; INPUT famid indid implicate imp_inc; CARDS ; 1 1 1 40000 1 1 2 25000 1 1 3 34000 1 1 4 23555 1 1 5 49850 1 2 1 1000 1 2 2 2000 1 2 3 3000 1 2 4 4000 1 2 5 5000 1 3 1 . 1 3 2 . 1 3 3 . 1 3 4 . 1 3 5 . 2 1 1 40000 2 1 2 45000
DATA have ;
INPUT famid indid implicate imp_inc;
CARDS ;
1 1 1 40000
1 1 2 25000
1 1 3 34000
1 1 4 23555
1 1 5 49850
1 2 1 1000
1 2 2 2000
1 2 3 3000
1 2 4 4000
1 2 5 5000
1 3 1 .
1 3 2 .
1 3 3 .
1 3 4 .
1 3 5 .
2 1 1 40000
2 1 2 45000
2 1 3 50000
2 1 4 34000
2 1 5 23500
2 2 1 .
2 2 2 .
2 2 3 .
2 2 4 .
2 2 5 .
2 3 1 41000
2 3 2 39000
2 3 3 24000
2 3 4 32000
2 3 5 53000
RUN ;
DATA want ;
INPUT famid indid implicate imp_inc;
CARDS ;
1 1 1 40000
1 1 2 25000
1 1 3 34000
1 1 4 23555
1 1 5 49850
1 2 1 40000
1 2 2 25000
1 2 3 34000
1 2 4 23555
1 2 5 49850
1 3 1 40000
1 3 2 25000
1 3 3 34000
1 3 4 23555
1 3 5 49850
2 1 1 40000
2 1 2 45000
2 1 3 50000
2 1 4 34000
2 1 5 23500
2 2 1 40000
2 2 2 45000
2 2 3 50000
2 2 4 34000
2 2 5 23500
2 3 1 40000
2 3 2 45000
2 3 3 50000
2 3 4 34000
2 3 5 23500
RUN ;
因此,我们有家庭id、个人id、牵连人数和每个牵连的估算收入
我需要的是复制每个家族中第一个个体的结果,每个家族中其余的个体都有五个牵连,取代我们之前对这些细胞的价值观,如下所示:
DATA have ;
INPUT famid indid implicate imp_inc;
CARDS ;
1 1 1 40000
1 1 2 25000
1 1 3 34000
1 1 4 23555
1 1 5 49850
1 2 1 1000
1 2 2 2000
1 2 3 3000
1 2 4 4000
1 2 5 5000
1 3 1 .
1 3 2 .
1 3 3 .
1 3 4 .
1 3 5 .
2 1 1 40000
2 1 2 45000
2 1 3 50000
2 1 4 34000
2 1 5 23500
2 2 1 .
2 2 2 .
2 2 3 .
2 2 4 .
2 2 5 .
2 3 1 41000
2 3 2 39000
2 3 3 24000
2 3 4 32000
2 3 5 53000
RUN ;
DATA want ;
INPUT famid indid implicate imp_inc;
CARDS ;
1 1 1 40000
1 1 2 25000
1 1 3 34000
1 1 4 23555
1 1 5 49850
1 2 1 40000
1 2 2 25000
1 2 3 34000
1 2 4 23555
1 2 5 49850
1 3 1 40000
1 3 2 25000
1 3 3 34000
1 3 4 23555
1 3 5 49850
2 1 1 40000
2 1 2 45000
2 1 3 50000
2 1 4 34000
2 1 5 23500
2 2 1 40000
2 2 2 45000
2 2 3 50000
2 2 4 34000
2 2 5 23500
2 3 1 40000
2 3 2 45000
2 3 3 50000
2 3 4 34000
2 3 5 23500
RUN ;
在这个例子中,我试图只复制一个变量,但在我的项目中,我将不得不对几十个变量进行复制
到目前为止,我提出了以下解决方案:
%let implist_1=imp_inc;
%macro copyv1(list);
%let nwords=%sysfunc(countw(&list));
%do i=1 %to &nwords;
%let varl=%scan(&list, &i);
proc means data=have max noprint;
var &varl;
by famid implicate;
where indid=1;
OUTPUT OUT=copy max=max_&varl;
run;
data want;
set have;
drop &varl;
run;
data want (drop=_TYPE_ _FREQ_);
merge want copy;
by famid implicate;
rename max_&varl=&varl;
run;
%end;
%mend;
%copyv1(&imp_list1);
这适用于一个或两个变量。然而,在一个大小为1.5 GB的数据集中对400个变量执行此操作时,速度会非常慢
我很确定有一种更快的方法可以通过某种形式的proc-sql或first.var等实现这一点,但我对SAS比较陌生,到目前为止,我还没有找到更好的解决方案
非常感谢您的支持
致以最诚挚的问候使用一点SQL,这相当简单:
proc sql;
create table want as
select a.famid, a.indid, a.implicate, b.* from
have a
left join (
select * from have
group by famid
having indid = min(indid)
) b
on
a.famid = b.famid
and a.implicate = b.implicate
order by a.famid, a.indid, a.implicate
;
quit;
其思想是将表连接到其自身的子集,该子集只包含与每个族中第一个个体对应的行
它被设置为拾取每个族中编号最低的个体,因此即使没有indid=1的行,它也可以工作。如果确定始终存在这样的行,则可以使用稍微简单一点的查询:
proc sql;
create table want as
select a.famid, a.indid, a.implicate, b.* from
have(sortedby = famid) a
left join have(where = (indid = 1)) b
on
a.famid = b.famid
and a.implicate = b.implicate
order by a.famid, a.indid, a.implicate
;
quit;
指定sortedby=famid会向查询优化程序提供一个提示,提示它可以跳过联接所需的一个初始排序,这可能会稍微提高性能。是的,这可以在数据步骤中使用第一个。通过by声明提供参考
data want;
set have (keep=famid indid implicate imp_inc /* other vars */);
by famid indid implicate; /* by implicate is so step logs an error (at run-time) if data not sorted */
if first.famid then if indid ne 1 then abort;
array across imp_inc /* other vars */;
array hold [1,5] _temporary_; /* or [<n>,5] where <n> means the number of variables in the across array */
if indid = 1 then do; /* hold data for 1st individuals implicate across data */
do _n_ = 1 to dim(across);
hold[_n_,implicate] = across[_n_]; /* store info of each implicate of first individual */
end;
end;
else do;
do _n_ = 1 to dim(across);
across[_n_] = hold[_n_,implicate]; /* apply 1st persons info to subsequent persons */
end;
end;
run;
由于单次传递数据,数据步骤可能会大大加快,但是在运行时计算所有这些讨厌的[]数组地址会带来内部处理成本;时间,而这一成本在某种程度上可能会产生影响
SQL语法更简单,理解更清晰,如果have数据集未排序或在by组中有一些特殊的排序,SQL也可以工作。感谢您的回复。我对sql了解不多,但这似乎复制了所有变量,对吗?如果我想选择一个子集,我需要将select imp_inc而不是select*,对吗?您还可以指定一个逗号分隔的变量列表,或使用数据集选项,例如select*from havekeep=key1-key3 firstvar lastvarIs源数据已经按FAMID排序,以便第一条记录是要复制的记录?如果要复制的值在第一条记录上丢失了怎么办?使用SQL过程,我的整个程序每次迭代运行需要11分钟;使用此解决方案需要9分钟。谢谢!伟大的欢迎使用堆栈溢出,了解有关