Dear All:
My Data is as follows Date ID ID_A Quarter 03JAN2017 1 A 1 04JAN2017 1 A 1 04APR2017 1 A 2 10MAY2017 1 A 2 09AUG2017 1 A 3 16FEB2017 1 B 1 18SEP2018 1 B 7 13JAN2017 2 A 1 15FEB2017 2 A 1 21JUN2017 2 A 2 14MAR2017 2 B 1 21NOV2017 2 B 4 I want to add another variable QBT indicating the quarters between transactions Date ID ID_A Quarter QBT 03JAN2017 1 A 1 1 04JAN2017 1 A 1 1 04APR2017 1 A 2 1 10MAY2017 1 A 2 1 09AUG2017 1 A 3 -50000 /* Just a flag */ 16FEB2017 1 B 1 6 18SEP2018 1 B 7 -50000 13JAN2017 2 A 1 1 15FEB2017 2 A 1 1 21JUN2017 2 A 2 -50000 14MAR2017 2 B 1 3 21NOV2017 2 B 4 -50000 The rules are as follows:
For ID = 1 and ID_A = A there are transactions in 3 Quarters -- 1, 2 and 3 so QBT is the difference between Quarter = 2 and Quarter = 1 So for the first two lines QBT = 1; then for the next two lines QBT = 1 also (3 -2). The last row of ID and ID_A is = -50000 The same logic applies to ID = 1 and ID_A = B
Thanx in Advance
R
data have;
input Date :$20. ID ID_A $ Quarter;
cards;
03JAN2017 1 A 1
04JAN2017 1 A 1
04APR2017 1 A 2
10MAY2017 1 A 2
09AUG2017 1 A 3
16FEB2017 1 B 1
18SEP2018 1 B 7
13JAN2017 2 A 1
15FEB2017 2 A 1
21JUN2017 2 A 2
14MAR2017 2 B 1
21NOV2017 2 B 4
;
run;
proc sort data=have(keep=id id_a quarter) out=temp nodupkey;
by id id_a quarter;
run;
data diff;
merge temp temp(firstobs=2 rename=(id=_id id_a=_id_a quarter=_quarter));
if id=_id and id_a=_id_a then diff=_quarter-quarter;
else diff=-50000;
drop _:;
run;
data want;
merge have diff;
by id id_a quarter;
run;
Dear Mr. KSharp:
Your solution does not result in the output that I need. Your solution of finding the difference gives the following
DATE ID ID_A QUARTER QBT
03JAN2017 1 A 1 0
04JAN2017 1 A 1 1
04APR2017 1 A 2 0
10MAY2017 1 A 2 1
09AUG2017 1 A 3 -50000
What I need is
DATE ID ID_A QUARTER QBT
03JAN2017 1 A 1 1
04JAN2017 1 A 1 1
04APR2017 1 A 2 1
10MAY2017 1 A 2 1
09AUG2017 1 A 3 -50000Please help
Thanx
R
I shamelessly stole the example data from @Ksharp and expanded the basic idea (as you need a "reverse" difference):
data have;
input Date :$20. ID ID_A $ Quarter;
cards;
03JAN2017 1 A 1
04JAN2017 1 A 1
04APR2017 1 A 2
10MAY2017 1 A 2
09AUG2017 1 A 3
16FEB2017 1 B 1
18SEP2018 1 B 7
13JAN2017 2 A 1
15FEB2017 2 A 1
21JUN2017 2 A 2
14MAR2017 2 B 1
21NOV2017 2 B 4
;
run;
proc sort
data=have(keep=id id_a quarter)
out=temp
nodupkey
;
by id id_a descending quarter;
run;
data diff;
set temp;
by id id_a;
qbt = lag(quarter) - quarter;
if first.id_a then qbt = -50000;
run;
proc sort data=diff;
by id id_a quarter;
run;
data want;
merge
have
diff
;
by id id_a quarter;
run;
proc print data=want noobs;
run;
Result:
Date ID ID_A Quarter qbt 03JAN2017 1 A 1 1 04JAN2017 1 A 1 1 04APR2017 1 A 2 1 10MAY2017 1 A 2 1 09AUG2017 1 A 3 -50000 16FEB2017 1 B 1 6 18SEP2018 1 B 7 -50000 13JAN2017 2 A 1 1 15FEB2017 2 A 1 1 21JUN2017 2 A 2 -50000 14MAR2017 2 B 1 3 21NOV2017 2 B 4 -50000
which matches your originally wanted result:
Date ID ID_A Quarter QBT 03JAN2017 1 A 1 1 04JAN2017 1 A 1 1 04APR2017 1 A 2 1 10MAY2017 1 A 2 1 09AUG2017 1 A 3 -50000 /* Just a flag */ 16FEB2017 1 B 1 6 18SEP2018 1 B 7 -50000 13JAN2017 2 A 1 1 15FEB2017 2 A 1 1 21JUN2017 2 A 2 -50000 14MAR2017 2 B 1 3 21NOV2017 2 B 4 -50000
That is really weird. Here is my output .
@RandyStan wrote:
Dear Mr. KSharp:
Your solution does not result in the output that I need. Your solution of finding the difference gives the following
DATE ID ID_A QUARTER QBT
03JAN2017 1 A 1 0 04JAN2017 1 A 1 1 04APR2017 1 A 2 0 10MAY2017 1 A 2 1 09AUG2017 1 A 3 -50000
What I need is
DATE ID ID_A QUARTER QBT
03JAN2017 1 A 1 1 04JAN2017 1 A 1 1 04APR2017 1 A 2 1 10MAY2017 1 A 2 1 09AUG2017 1 A 3 -50000Please help
Thanx
R
You must have run something different, as @Ksharp's code
data have;
input Date :$20. ID ID_A $ Quarter;
cards;
03JAN2017 1 A 1
04JAN2017 1 A 1
04APR2017 1 A 2
10MAY2017 1 A 2
09AUG2017 1 A 3
16FEB2017 1 B 1
18SEP2018 1 B 7
13JAN2017 2 A 1
15FEB2017 2 A 1
21JUN2017 2 A 2
14MAR2017 2 B 1
21NOV2017 2 B 4
;
run;
proc sort data=have(keep=id id_a quarter) out=temp nodupkey;
by id id_a quarter;
run;
data diff;
merge temp temp(firstobs=2 rename=(id=_id id_a=_id_a quarter=_quarter));
if id=_id and id_a=_id_a then diff=_quarter-quarter;
else diff=-50000;
drop _:;
run;
data want;
merge have diff;
by id id_a quarter;
run;
proc print data=want noobs;
run;
gives me the same result as mine:
Date ID ID_A Quarter diff 03JAN2017 1 A 1 1 04JAN2017 1 A 1 1 04APR2017 1 A 2 1 10MAY2017 1 A 2 1 09AUG2017 1 A 3 -50000 16FEB2017 1 B 1 6 18SEP2018 1 B 7 -50000 13JAN2017 2 A 1 1 15FEB2017 2 A 1 1 21JUN2017 2 A 2 -50000 14MAR2017 2 B 1 3 21NOV2017 2 B 4 -50000
which also matches your originally wanted result.
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.