比较行之间的值,然后删除SAS中的重复值



我有一个数据集,它有某些变量,现在我必须在行之间比较这些变量以找到重复的变量,但它几乎没有额外的请求。

  • if对于相同的acct_num和test_id

如果final_amt与下一行的final_amt匹配,并且final_amt_added与下一行将的final_amt_added匹配,则我们必须将它们视为重复,并仅删除trans_date为空的情况。

-此外,如果我们要删除trans_date为空的重复行,则该行的actual_amt数据应作为新变量act_amt_extra保留在未删除的行中。

我已经尝试了使用滞后和保留的多个场景,但数据不正确,任何帮助都将不胜感激。

DATA work.sample;
INPUT acct_num test_id tran_date:anydtdte. actual_amt final_amt final_amt_added ;
format tran_date date9.;
DATALINES; 
55203610 2542 12-jan-20 30 45 45
16124130 8062 .         56 78 78 
16124130 8062 14-dec-19 8  78 78
80479512 2062 19-mar-19 32 32 32
70321918 2062 20-dec-19 1  93 54
17312410 6712 .         45 90 90
17312410 6712 15-jun-18 0  90 90
74623123 2092 17-aug-18 34 87 87
24245321 2082 22-jan-17 22 56 67
;
run;

我想要的数据

data want;
input acct_num test_id tran_date:anydtdte. actual_amt final_amt final_amt_added act_amt_extra;
format tran_date date9.;
DATALINES; 
55203610 2542 12-jan-20 30 45 45
16124130 8062 14-dec-19 8  78 78 56
80479512 2062 19-mar-19 32 32 32
70321918 2062 20-dec-19 1  93 54
17312410 6712 15-jun-18 0  90 90 45
74623123 2092 17-aug-18 34 87 87
24245321 2082 22-jan-17 22 56 67
;
run;

这可能不是最优雅的处理方式,但只要您只有一个重复,它就会起作用,如您的示例所示。

我们最感兴趣的数据是当日期而不是丢失时。首先,按acct_num test_id和降序tran_date:对数据进行排序

proc sort data=sample;
by acct_num test_id descending tran_date;
run;

这确保了我们关心的数据是第一位的:

acct_num    test_id tran_date   actual_amt  final_amt   final_amt_added
16124130    8062    14DEC2019   8           78          78
16124130    8062    .           56          78          78

我们只想在acct_num test_id的最后一个组合中输出。当存在重复时,我们希望将以下值向前拉:

  • tran_date
  • actual_amt

注意,当存在重复并且我们想要向前拉值时,我们知道以下内容:

  • last.test_id为真
  • first.test_id为假
  • tran_date丢失
  • final_amt与前一行的值匹配
  • final_amt_added与前一行的值匹配

当这种情况发生时,我们将运行我们的逻辑。否则,我们将保持行的原样并输出。

data want;
set sample;
by acct_num test_id descending tran_date;
/* Store prior values */
lag_actual_amt      = lag(actual_amt);
lag_final_amt_added = lag(final_amt_added);
lag_final_amt       = lag(final_amt);
lag_tran_date       = lag(tran_date);
/* Bring forward data if conditions are met */
if( missing(tran_date)
AND last.test_id 
AND NOT first.test_id
AND final_amt       = lag_final_amt
AND final_amt_added = lag_final_amt_added
)
then do;
act_amt_extra = actual_amt;
/* Bring forward the prior values */
tran_date     = lag_tran_date;
actual_amt    = lag_actual_amt;
end;
/* Only output for the last combination of acct_num, test_id */
if(last.test_id);
drop lag:;
run;

这里有一种非常优雅的方式来满足您的需求:

proc sort data=sample;
by acct_num tran_date;
run;
data want;
set sample;
by acct_num tran_date;
act_amt_extra = lag(actual_amt);
if first.acct_num then act_amt_extra = .;
if tran_date = . then delete; 
run;

最新更新