vHi,
I'd like to change the dataset
From
Acct | mail date | Order |
111 | 1-Jan | 1 |
111 | 1-Feb | 2 |
111 | 1-Mar | 3 |
222 | 1-Jan | 1 |
222 | 1-Apr | 2 |
To
Acct | Order 1 | Order 2 | Order 3 |
111 | 1-Jan | 1-Feb | 1-Mar |
222 | 1-Jan | 1-Apr |
How can I do this in SAS?
Thanks,
Kwang
You can do it with the following program.
data kyoo;
input Acct maildate$ Order;
cards;
111 1-Jan 1
111 1-Feb 2
111 1-Mar 3
222 1-Jan 1
222 1-Apr 2
;
proc transpose data=b;
var maildate;
by acct;
run;
If the order is always sequential it isn't even needed.
data have;
input Acct maildate $ Order ;
datalines;
111 1-Jan 1
111 1-Feb 2
111 1-Mar 3
222 1-Jan 1
222 1-Apr 2
run;
/* assumes data is sorted by acct and order number*/
proc transpose data=have out=want (drop=_name_)
prefix=order
;
by acct;
var maildate;
run;
Hi Kyoo,
Proc transpose would work fine for your data. But what if the data is like this...
111 1-Jan 1
111 1-Feb 3
111 1-Mar 4
222 1-Jan 1
222 1-Apr 3
Order2 will not be included in your output. For this u have to go with data step as given below,
DATA HAVE;
INPUT Acct mail_date $ Order;
DATALINES;
111 1-Jan 1
111 1-Feb 3
111 1-Mar 4
222 1-Jan 1
222 1-Apr 3
;
RUN;
*Selecting the maximum of order;
PROC SQL NOPRINT;
SELECT MAX(ORDER) INTO :M_ORD FROM HAVE ;
QUIT;
PROC SORT DATA=HAVE;
BY ACCT;
RUN;
DATA WANT(DROP=ORD MAIL_DATE I);
SET HAVE (RENAME=(ORDER=ORD));
ARRAY ORDER(&M_ORD) $ ;
BY ACCT;
RETAIN ORDER: ;
IF FIRST.ACCT THEN
DO I = 1 TO &M_ORD;
ORDER(I)=" ";
END;
ORDER(ORD)= MAIL_DATE;
IF LAST.ACCT;
RUN;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.