split row into two columns with sas proc transpose - sas

I have a data set that looks like:
unit A1 B1 A2 B2 A3 B3 ....
.
.
.
I need to convert it to:
unit A B
1
2
3
I can transpose each separately with:
proc transpose data=test OUT=TESTOUT;
var A1-A5 B1-B5;
BY UNIT;
but this gives me 1 long column instead of 2

proc transpose data=test out=test1(rename=(col1=dat));
by id;
var dat1-dat5;
run;
proc transpose data=test out=test2(rename=(col1=rec));
by id;
var rec1-rec5;
run;
data test3 (drop=_name_);
merge test1 test2;
by id;
run;

Related

SAS transpose columns to row and values to columns

I have a summary table which I want to transpose, but I can't get my head around. The columns should be the rows, and the columns are the values.
Some explanation about the table. Each column represents a year. People can be in 3 groups: A, B or C. In 2016, everyone (100) is in group A. In 2017, 35 are in group A (5 + 20 + 10), 15 in B and 50 in C.
DATA have;
INPUT year2016 $ year2017 $ year2018 $ count;
DATALINES;
A A A 5
A A B 20
A A C 10
A B C 15
A C A 50
;
RUN;
I want to be able to make a nice graph of the evolution of the groups through the different periods. So I want to end up with a table where the columns are the rows (=period) and the columns are the values (= the 3 different groups). Please find an example of the table I want:
Image of table want
I have tried different approaches, but I can't get what I want.
Maybe more direct way but this is probably how I would do it.
DATA have;
INPUT year2016 $ year2017 $ year2018 $ count;
id + 1;
DATALINES;
A A A 5
A A B 20
A A C 10
A B C 15
A C A 50
;
RUN;
proc print;
proc transpose data=have out=want1 name=period;
by id count notsorted;
var year:;
run;
proc print;
run;
proc summary data=want1 nway completetypes;
class period col1;
freq count;
output out=want2(drop=_type_);
run;
proc print;
run;
proc transpose data=want2 out=want(drop=_name_) prefix=Group_;
by period;
var _freq_;
id col1;
run;
proc print;
run;

SAS - proc sql - select columns belonging together?

I want to split a table with many (454) columns in a PROC SQL (perhaps using a macro?) by column names.
For example: a column is starting with "Column21....T", "Column22....T", etc.
I want to write all those columns starting with "Column21...T" to a data set called First, and all the columns starting with "Column22....T" to a data set called Second, etc.
I want to retain the first and second column of the transposed table because they contain the descriptional rows.
I cannot use select column1, column2.... Column454 because of the large number of columns.
How do I do this?
(#Mod: thanks for the clean-up :))
Edit, one picture to say it all:
This is my transposed table with 454 columns
PROC SORT
DATA=work.stat(KEEP=A_ B_ C_ D_ Vx G Vy)
OUT=work.stat2;
BY G;
RUN;
PROC TRANSPOSE DATA=work.stat2
OUT=WORK.x(LABEL="Transposed")
PREFIX=Column
LET
NAME=Source
LABEL=Label;
BY G;
ID Vx;
IDLABEL Vy;
VAR A_ B_ C_ D_;
RUN;
You can use : suffix to make a variable list.
data first ;
set have ;
keep id1 id2 column21: ;
run;
data second ;
set have ;
keep id1 id2 column22: ;
run;
Updated given more details in question.
So why not just transpose each group separately? Make a macro to transpose one value of Vx.
%macro split(value);
PROC TRANSPOSE DATA=work.stat2
OUT=WORK.Column&value (LABEL="Transposed Vx=&value")
PREFIX=Column
LET
NAME=Source
LABEL=Label
;
BY G;
WHERE Vx=&value ;
ID Vx;
IDLABEL Vy;
VAR A_ B_ C_ D_;
RUN;
%mend split ;
Then call it once for each value of Vx.
proc sort data=work.stat2(keep=Vx) nodupkey out=Vx_list ;
by Vx ;
run;
data _null_;
set Vx_list;
call execute(cats('%nrstr(%split)(',Vx,')'));
run;
Macro program:
%macro split(data,outdata);
%do i=21 %to 121;
data &outdata.&i;
set &data;
keep id1 id2 col&i:;
run;
%end;
%mend;

Setting names to idgroup

Follow up to
SAS - transpose multiple variables in rows to columns
I have the following code:
data have;
input CX_ID 1. TYPE $1. COUNT_RATE 1. SUM_RATE 2.;
datalines;
1A110
1B220
2A120
;
run;
proc summary data = have nway;
class cx_id;
output out=want (drop = _:)
idgroup(out[2] (count_rate sum_rate)= count sum);
run;
So this table:
CX_ID TYPE COUNT_RATE SUM_RATE
1 A 1 10
1 B 2 20
2 A 1 20
becomes
CX_ID COUNT_1 COUNT_2 SUM_1 SUM_2
1 1 2 10 20
2 1 . 20 .
Which is perfect, but how do I set the names to be
Count_A Count_B Sum_A Sum_B
Or in general whatever the value in the type field of the have table ?
Thank you
A double PROC TRANSPOSE is dynamic and you can add a data step to customize the names easily.
*sample data;
data have;
input CX_ID 1. TYPE $1. COUNT 1. SUM 2.;
datalines;
1A110
1B220
2A120
;
run;
*transpose to long;
proc transpose data=have out=long;
by cx_id type;
run;
*transpose to wide;
proc transpose data=long out=wide;
by cx_id;
var col1;
id _name_ type;
run;

Transpose the dataset

I have the original dataset
What I want is:
My code:
proc transpose data = lib.original
out= lib.new(rename=(col1=Mean col2=Median));
var WBCmean RBCmean WBCmedian RBCmedian;
run;
But I get
Can you give some hint?
EDIT
If I add by statement,
proc transpose data = lib.original
out= lib.new;
by Gender;
var WBCmean RBCmean WBCmedian RBCmedian;
run;
then I get
One way is to convert to a tall skinny format.
proc transpose data = have out=middle ;
by gender ;
var WBCmean RBCmean WBCmedian RBCmedian;
run;
Then generate the new variables needed,
data middle;
set middle ;
testcode = substr(_name_,1,3);
_name_ = substr(_name_,4);
run;
you might need to sort the data depending on the order of variable names in your original VAR statement,
proc sort data=middle;
by gender testcode _name_;
run;
and then transpose into the new arrangement.
proc transpose data=middle out=want ;
by gender testcode ;
id _name_;
var col1 ;
run;

How to create macro variable from a column of dataset using data step not SQL?

We can make macro variables via the SAS SQL Procedure, using the syntax
select var into :mvar
But I wonder if there's same way in data step.
I have a dataset.
A B
=== ===
a1 b1
a2 b2
a3 b3
I can make a macro variable called MA with the below statement.
proc sql noprint;
select "'"||A||"'" into :MA separated by ","
from dataset;
quit;
How to do it in Data-step?
Firstly, creating your sample dataset:
data dataset;
infile datalines;
input A $ B $;
datalines;
a1 b1
a2 b2
a3 b3
;
run;
The step below almost does what your PROC SQL does, using CALL SYMPUT to output a macro variable called MA:
data _NULL_;
retain amac;
length amac $35;
set dataset;
if _N_ = 1 then amac=a; else amac=cats(amac,',',a);
put amac=;
call symputx('MA',amac);
run;
%put &MA;