BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
darkmoon178
Calcite | Level 5

Hi everyone,

I'm new with SAS and I am trying to transpose multiple variable from wide to long, as in the example mention below

The A,B,C is the prefix followed by time (year).

 

ID   Name   FirmID   A1981   A1982 ... B1981   B1982... C1981  C1982...

1     x           123         2           3             4             5            6            7

2     y           124        22         33           44           55         66           77

3     z           555       222        333         444         555        666       777

 

I don't know how to use prefix (A,B,C) and transpose by year. In addition, is there any code so that I can combine to transpose to multiple variables by year, or I have to do that for 3 times from wide to long (one for A, one for B, and one for C)?

This is the data I want to get:

 

ID   Name   FirmID    Year             A              B                C

1     x           123        1981          2               4                 6

1     x           123        1982          3               5                 7

.......

2     y           124        1981          22           44                66

2     y           124        1982          33           55                77

.........

3     z           555        1981          222          444            666

3     z           555        1982          333          555            777

 

I'm appreciate any help 🙂

 

1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20

Hi @darkmoon178, seems your 1st post, so welcome to the sas forum.

 

First off, Below is an easy yet inefficient solution as I do have a one step datastep based solution in my mind, however feeling lazy at 5:15 pm Saturday to pen that down. I am sure somebody will post the efficient solution  shortly. Until then you can play with mine. 

 

data have;
input ID $  Name $   FirmID $   A1981   A1982  B1981   B1982 C1981  C1982;
cards;
1     x           123         2           3             4             5            6            7
2     y           124        22         33           44           55         66           77
3     z           555       222        333         444         555        666       777
;
 
proc transpose data=have out=t;
by id name firmid;
var _numeric_;
run;
data t1;
set t;
year=input(compress(_name_,,'kd'),8.);
v=first(_name_);
run;

proc sort data=t1 out=t2;
by id name firmid year;
run;

proc transpose data=t2 out=want(drop=_name_);
by id name firmid year;
var col1;
id v;
run;

 

 

 

 

View solution in original post

6 REPLIES 6
novinosrin
Tourmaline | Level 20

Hi @darkmoon178, seems your 1st post, so welcome to the sas forum.

 

First off, Below is an easy yet inefficient solution as I do have a one step datastep based solution in my mind, however feeling lazy at 5:15 pm Saturday to pen that down. I am sure somebody will post the efficient solution  shortly. Until then you can play with mine. 

 

data have;
input ID $  Name $   FirmID $   A1981   A1982  B1981   B1982 C1981  C1982;
cards;
1     x           123         2           3             4             5            6            7
2     y           124        22         33           44           55         66           77
3     z           555       222        333         444         555        666       777
;
 
proc transpose data=have out=t;
by id name firmid;
var _numeric_;
run;
data t1;
set t;
year=input(compress(_name_,,'kd'),8.);
v=first(_name_);
run;

proc sort data=t1 out=t2;
by id name firmid year;
run;

proc transpose data=t2 out=want(drop=_name_);
by id name firmid year;
var col1;
id v;
run;

 

 

 

 

darkmoon178
Calcite | Level 5

Thank you so much. I really appricate your help and I will try yours

I also figure out use these codes:

 

proc transpose data=data out=data1 prefix=A;
by id name FirmID;
var A1981-A1982;
run;

 

proc transpose data=data out=data2 prefix= B;
by id name FirmID;

var B1981-B1982;
run;

 

proc transpose data=data out=data3 prefix= C;
by id name FirmID;

var C1981-C1982;
run;

 

data datafinal;
merge data1 (rename=(A1=A) drop = _name_)
data2 (rename=(B1=B) drop =_name_)
data3 (rename=(C1=C));
by id name FirmID;

year=input(substr(_name_, 5),5.);
drop _name_ _label_;
run;

novinosrin
Tourmaline | Level 20

Good try and your effort is well appreciated. 

However

var A1981-A1982;

 

is hard coding and potentially tons of it may arise in a typical production automated environment. So speed up your learning imho. Have fun!

 

singhsahab
Lapis Lazuli | Level 10

Hello Dear,

 

Just simplified your code by macro .

 

data have;
input
ID & Name & $ FirmID & A1981 & A1982 & B1981 & B1982 & C1981 & C1982 &;
datalines;
1 x 123 2 3 4 5 6 7

2 y 124 22 33 44 55 66 77

3 z 555 222 333 444 555 666 777
;
run;

%macro tran(out=,var_v=,pre_v=);
proc transpose data=have out=&out (rename=(&var_v=&pre_v _name_=year)) prefix=&pre_v;
by id name firmid;
var &var_v:;
run;
%mend;

 

/*Calling Macro*/

 

%tran(out=a_dataset,var_v=a1,pre_v=a);
%tran(out=b_dataset,var_v=b1,pre_v=b);
%tran(out=c_dataset,var_v=c1,pre_v=c);

 

data want;
merge a_dataset b_dataset c_dataset;
by id name firmid;
year=input(substr(year,2),8.);
run;

 

acerickson
Obsidian | Level 7

thanks for posting a Macro solution. Much appreciated!

 

I think there is an error in the data creation code, but the macro works perfect.

Astounding
PROC Star

To avoid multiple steps, you would need to do a little coding.  I'm not sure how many variables you actually have here, so I will illustrate with three sets.

 

data want;

set have;

array newvars {3} A B C;

array oldvars {3, 1981:1982} A1981 A1982 B1981 B1982 C1981 C1982;

do year = 1981 to 1982;

   do k=1 to 3;

      newvars{k} = oldvars{k, year};

   end;

   output;

end;

keep id Name FirmID A B C;

run;

 

It's untested, so you'll need to verify whether I got the array elements in the proper order.

 

While it wouldn't be as sophisticated, it's nearly as easy just hard-coding the whole thing:

 

data want;

set have;

Year = 1981;

A = A1981;

B = B1981;

C = C1981;

output;

Year = 1982;

A = A1982;

B = B1982;

C = C1982;

output;

keep ID Name FirmID Year A B C;

run;

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 18139 views
  • 5 likes
  • 5 in conversation