比较行之间的值,然后删除SAS中的重复值
Comparing values among rows and then deleting the duplicate values in SAS
我有一个包含某些变量的数据集,现在我必须在行之间比较这些变量以找到重复项,但它几乎没有额外的要求。
- if 对于相同的 acct_num 和 test_id
- 如果 final_amt 匹配下一行的 final_amt 并且 final_amt_added 匹配下一行的 final_amt_added 我们必须将它们视为重复项并仅删除tran_date 为空的情况。
- 此外,如果我们要删除带有空白 tran_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;
我有一个包含某些变量的数据集,现在我必须在行之间比较这些变量以找到重复项,但它几乎没有额外的要求。
- if 对于相同的 acct_num 和 test_id
- 如果 final_amt 匹配下一行的 final_amt 并且 final_amt_added 匹配下一行的 final_amt_added 我们必须将它们视为重复项并仅删除tran_date 为空的情况。
- 此外,如果我们要删除带有空白 tran_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;