It is more logic to require loandate >= campaign_date or more precisely as in my first post:
"Your requirement is to find the last campaign prior the loan_date.".
It easy to fit the code to that requirement:
%let last_cmpgn = 4; /* adapt number to max campaingns */
data want;
set have;
array cm {*} campaign_date1-campaign_date&last_cmpgn;
do i=1 to dim(cm);
j = i+1;
if loandate=. then leave; else
if (j <= &last_cmpgn and cm(j)=.) or i=&last_cmpgn then do;
if i>1 then campaign_converted = cm(i-1);
else campaign_converted = cm(i); /* or missing ??? */
leave;
end;
else
if cm(j) > loandate then do;
campaign_converted = cm(i);
leave;
end;
end;
drop i j;
run;
Please provide your sample data in the form of a working data step. You will benefit more if we invest our time in helping you diagnose the problem rather than in making a working sas data set from your excel sheet - which some people won't download for security reasons.
Also show us what you got, contrasted to what you expected. Otherwise we are examining a problem statement that is not far enough above the all-too-common "doesn't work" characterization.
Help us help you.
here is the example data. the objective is to find 'campaign_converted' where campaign_converted is loandate ge campaign_date(n)
CUSTOMER | campaign_date1 | campaign_date2 | campaign_date3 | campaign_date4 | LOANDATE | CAMPAIGN_CONVERTED |
CUSTOMER 1 | 04/09/2019 | 05/31/2019 | ||||
CUSTOMER 2 | 07/02/2019 | 08/14/2019 | ||||
CUSTOMER 3 | 09/19/2019 | 08/20/2020 | 10/22/2020 | 12/09/2020 | ||
CUSTOMER 4 | 04/09/2019 | 08/20/2020 | 10/22/2020 | 12/09/2020 | ||
CUSTOMER 5 | 06/23/2020 | 09/25/2020 | 11/11/2020 | |||
CUSTOMER 6 | 11/11/2020 | |||||
CUSTOMER 7 | 07/02/2019 | 08/16/2019 | ||||
CUSTOMER 8 | 07/17/2020 | 10/22/2020 | 12/09/2020 | |||
CUSTOMER 9 | 04/09/2019 | 07/05/2019 | ||||
CUSTOMER 10 | 04/09/2019 | 05/24/2019 | ||||
CUSTOMER 11 | 06/23/2020 | |||||
CUSTOMER 12 | 06/23/2020 | 09/25/2020 | 11/11/2020 | |||
CUSTOMER 13 | 04/09/2019 | 08/20/2020 | 12/09/2020 | |||
CUSTOMER 14 | 04/09/2019 | 04/11/2019 | ||||
CUSTOMER 15 | 07/17/2020 | 10/22/2020 | ||||
CUSTOMER 16 | 04/09/2019 | 12/23/2019 | ||||
CUSTOMER 17 | 04/09/2019 | 05/18/2019 | ||||
CUSTOMER 18 | 04/09/2019 | 05/28/2019 | ||||
CUSTOMER 19 | 04/09/2019 | 04/29/2019 | ||||
CUSTOMER 20 | 10/22/2020 | 12/09/2020 | ||||
CUSTOMER 21 | 12/09/2020 | 12/30/2020 | ||||
CUSTOMER 22 | 04/09/2019 | 07/10/2019 | ||||
CUSTOMER 23 | 04/09/2019 | 04/13/2019 | ||||
CUSTOMER 24 | 04/09/2019 | 04/20/2019 | ||||
CUSTOMER 25 | 04/09/2019 | 08/08/2020 | ||||
CUSTOMER 26 | 04/09/2019 | 08/30/2019 | ||||
CUSTOMER 27 | 04/09/2019 | 12/22/2019 | ||||
CUSTOMER 28 | 07/02/2019 | 08/06/2019 | ||||
CUSTOMER 29 | 04/09/2019 | 02/04/2020 | ||||
CUSTOMER 30 | 12/09/2020 | |||||
CUSTOMER 31 | 04/09/2019 | 06/25/2019 | ||||
CUSTOMER 32 | 06/23/2020 | 09/25/2020 | 11/11/2020 | |||
CUSTOMER 33 | 06/23/2020 | 09/25/2020 | 10/07/2020 | |||
CUSTOMER 34 | 04/09/2019 | 04/15/2019 | ||||
CUSTOMER 35 | 04/09/2019 | 05/10/2019 | ||||
CUSTOMER 36 | 04/09/2019 | 07/25/2019 | ||||
CUSTOMER 37 | 04/09/2019 | 08/20/2020 | 10/22/2020 | 12/09/2020 | ||
CUSTOMER 38 | 02/18/2019 | 06/28/2019 | ||||
CUSTOMER 39 | 04/09/2019 | 05/11/2019 | ||||
CUSTOMER 40 | 07/02/2019 | 08/15/2019 | ||||
CUSTOMER 41 | 07/02/2019 | |||||
CUSTOMER 42 | 06/23/2020 | 11/11/2020 | ||||
CUSTOMER 43 | 04/09/2019 | 11/02/2019 | ||||
CUSTOMER 44 | 04/09/2019 | 08/20/2020 | 10/22/2020 | 12/09/2020 | ||
CUSTOMER 45 | 08/20/2020 | 10/22/2020 | 12/09/2020 | 12/07/2020 | ||
CUSTOMER 46 | 07/02/2019 | |||||
CUSTOMER 47 | 04/09/2019 | 11/22/2019 |
Check next code:
data have;
informat campaign_date1-campaign_date4 loandate mmddyy10.;
format campaign_date1-campaign_date4 loandate mmddyy10.;
infile cards truncover dlm='09'x dsd;
input CUSTOMER_KEY
campaign_date1
campaign_date2
campaign_date3
campaign_date4
/* LOAN_KEY */
/* CASH_AMT */
/* LOAN_BALANCE */
loandate
/* PRODUCT_TYPE */
;
cards;
1 04/09/2019 05/31/2019
2 07/02/2019 08/14/2019
3 09/19/2019 08/20/2020 10/22/2020 12/09/2020
4 04/09/2019 08/20/2020 10/22/2020 12/09/2020
5 06/23/2020 09/25/2020 11/11/2020
6 11/11/2020
7 07/02/2019 08/16/2019
8 07/17/2020 10/22/2020 12/09/2020
9 04/09/2019 07/05/2019
10 04/09/2019 05/24/2019
11 06/23/2020
12 06/23/2020 09/25/2020 11/11/2020
13 04/09/2019 08/20/2020 12/09/2020
14 04/09/2019 04/11/2019
15 07/17/2020 10/22/2020
16 04/09/2019 12/23/2019
17 04/09/2019 05/18/2019
18 04/09/2019 05/28/2019
19 04/09/2019 04/29/2019
20 10/22/2020 12/09/2020
21 12/09/2020 12/30/2020
22 04/09/2019 07/10/2019
23 04/09/2019 04/13/2019
24 04/09/2019 04/20/2019
25 04/09/2019 08/08/2020
26 04/09/2019 08/30/2019
27 04/09/2019 12/22/2019
28 07/02/2019 08/06/2019
29 04/09/2019 02/04/2020
30 12/09/2020
31 04/09/2019 06/25/2019
32 06/23/2020 09/25/2020 11/11/2020
33 06/23/2020 09/25/2020 10/07/2020
34 04/09/2019 04/15/2019
35 04/09/2019 05/10/2019
36 04/09/2019 07/25/2019
37 04/09/2019 08/20/2020 10/22/2020 12/09/2020
38 02/18/2019 06/28/2019
39 04/09/2019 05/11/2019
40 07/02/2019 08/15/2019
41 07/02/2019
42 06/23/2020 11/11/2020
43 04/09/2019 11/02/2019
44 04/09/2019 08/20/2020 10/22/2020 12/09/2020
45 08/20/2020 10/22/2020 12/09/2020 12/07/2020
46 07/02/2019
47 04/09/2019 11/22/2019
;
run;
%let last_cmpgn = 4; /* adapt number to max campaingns */
data want;
set have;
array cm {*} campaign_date1-campaign_date&last_cmpgn;
do i=1 to dim(cm);
j = i+1;
if loandate=. then leave; else
if (j <= &last_cmpgn and cm(j)=.) or i=&last_cmpgn then do;
if i>1 then campaign_converted = cm(i-1);
else campaign_converted = cm(i); /* or missing ??? */
leave;
end;
else
if cm(j) > loandate then do;
campaign_converted = cm(i);
leave;
end;
end;
drop i j;
FORMAT campaign_converted MMDDYY10.;
run;
In case of any issue please explain it and post the right campaign_converted expected.
Hello - thanks always for your help. I ran your code and it did not work as expected. I've got rows that did not meet the objective.
see example: the code picked up the wrong campaign_date(n), campaign_converted should be campaign_date3.
CUSTOMER | campaign_date1 | campaign_date2 | campaign_date3 | campaign_date4 | LOANDATE | CAMPAIGN_CONVERTED |
CUSTOMER A | 06/23/2020 | 09/25/2020 | 11/11/2020 | 11/28/2020 | 09/25/2020 |
Bug is fixed:
%let last_cmpgn = 4; /* adapt number to max campaingns */
data want1;
set have;
array cm {*} campaign_date1-campaign_date&last_cmpgn;
do i=1 to dim(cm);
j = i+1;
if loandate=. then leave; else
if (j <= &last_cmpgn and cm(j)=.) or i=&last_cmpgn then do;
if i>1 then campaign_converted = cm(j-1); /* <<< line changed */
else campaign_converted = cm(i); /* or missing ??? */
leave;
end;
else
if cm(j) > loandate then do;
campaign_converted = cm(i);
leave;
end;
end;
drop i j;
FORMAT campaign_converted MMDDYY10.;
run;
You better read the sas documentation of using arrays.
Search by google for "sas documentation array".
Anyhow I shall try to give you some hints:
1) VAR1-VAR4 is a short code for the list VAR1 VAR2 VAR3 VAR4.
2) By defining an array like:
array cm {*} campaign_date1-campaign_date&last_cmpgn;
it enables to point easily to any member of the list, thus:
cm(1) is equivalent to campaign1 - the first member in the list.
cm(2) is equivalent to campaign2 - the first member in the list. etc.
3) Arrays' member is easily pointed by an any numeric variable like i, j
thus enable pointing forwards or backwards by adding/subtracting its value.
4) I suggest you to add some PUTLOG statements in the code to get the values
at run time of specific variables and learn why code worked as it worked.
I'm not sure my English is good enough to explain better.
If I understand correctly there are 4 campaigns named vampaign1-campagin4 and named chronologically. Your requirement is to find the last campaign prior the loan_date.
data want;
set have;
array cm {} campaign1-campaign4;
do i=1 to 4;
if loan_date < cm(i) then do;
j = max(1, i-1);
campaign_converted = vname(cm(j));
leave;
end;
else if i=4 then campaign_converted = vname(cm(i));
end;
drop i j;
run;
@Eugenio211 wrote:
thank you, the requirement is the to find the campaign date ge the loan date.
In this case next code will find the first campaign date > loan_date:
data want; set have; array cm {} campaign1-campaign4; do i=1 to 4; if loan_date < cm(i) or i=4 then do; campaign_converted = vname(cm(j)); leave; end; end; drop i; run;
Pay attention - in case there is no campaign date >= loan date you will get campaign4.
Try this:
data can_approvals3_t;
set can_approvals2_t;
format CAMPAIGN_CONVERTED mmddyy.;
array cd campaign_date1 - campaign_date4;
do i = 4 to 1 by -1 until (CAMPAIGN_CONVERTED);
if load_date >= coalesce(cd{i}, constant("BIG")) then
CAMPAIGN_CONVERTED = cd{i};
end;
drop i;
run;
(untested)
Sorry about that. Please provide usable data for testing (not Excel, not too large)
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.