How to transpose data with many columns in SAS - sas

Hi I new in SAS and I have a problem. I have the data which contains 337 rows and 64 columns.
It looks like this:
enter image description here
I need to make like this:
enter image description here
I've tried to use proc transpose, but I felt.
Please help.

You will need to TRANSPOSE BY DATE and then SORT by country date, I presume country is from the label of the original variables.
Example:
3 dates and 5 variables, easily changed for larger data.
data total_returns(label='Example data');
do date = '01jan2020'd to '03jan2020'd;
array RI RI_1-RI_5;
do over ri;
demo_value + 1;
RI = demo_value;
end;
output;
end;
label
RI_1 = 'MSCI Country Biff blah blah blah'
RI_2 = 'MSCI Country Bam blah blah blah'
RI_3 = 'MSCI Country Boom blah blah blah'
RI_4 = 'MSCI Country Zwok blah blah blah'
RI_5 = 'MSCI Country Pow blah blah blah'
;
format date yymmdd10.;
drop demo_value;
run;
proc transpose
data=total_returns
out=stage1 (
drop=_name_
rename= ( _label_=Country
col1 = RI
)
)
;
by date;
var RI_1-RI_5;
label country = ' ';
run;
proc sort data=stage1 out=want;
by country date;
run;
proc print label data=total_returns;
title "Original, across/array layout";
proc print data=want;
title "Transposed and Sorted, categorical/vector layout";
run;
Output:

Related

SAS combine two columns in a dataset

I got a dataset looks like this:
Category
Sub-Category
value
A
1
xx
A
2
xx
A
3
xx
A
4
xx
B
1
xx
B
2
xx
B
3
xx
B
4
xx
I want to combine the first two columns and create a new dataset with the new category(rows) and it should looks like this:
Category
Value
A
1
xx
2
xx
3
xx
4
xx
B
1
xx
2
xx
3
xx
4
xx
...
Can anyone help me with that using SAS?
Thanks in advance!
That seems pretty useless as a DATASET.
Why not just print the original dataset.
proc print data=have;
by category;
run;
Result:
If you did want to generate that goofy dataset you could try interleaving two copies of the original data.
data want;
set have(in=in1) have(in=in2);
by category;
if in1 then do;
if first.category then call missing(value);
else delete;
end;
if in2 then category=cats(subcategory);
drop subcategory ;
run;
Result:
You can do this in a data step with multiple output statements. The only tricky part is the first row: you'll need to retain the original value to create the "header" row, output, then output a second time to create the first subcategory row.
data want;
set have end=eof;
by category subcategory;
if(first.category) then do;
/* "Header" row: */
_value_ = value;
value = ' ';
output;
/* First subcategory row: */
value = _value_;
category = strip(subcategory);
output;
end;
/* Subsequent subcategory rows */
else do;
category = strip(subcategory);
output;
end;
/* Add a space between categories except the last row */
if(last.category AND NOT eof) then do;
call missing(value, category);
output;
end;
drop _value_ subcategory;
run;
Result:
category value
A
1 xx
2 xx
3 xx
4 xx
B
1 xx
2 xx
3 xx
4 xx
data have;
input Category $ SubCategory value $;
datalines;
A 1 xx
A 2 xx
A 3 xx
A 4 xx
B 1 xx
B 2 xx
B 3 xx
B 4 xx
;
data want;
set have;
by Category;
if first.Category then do;
v = value;
value = '';
output;
value = v;
Category = put(SubCategory, 8. -l);
output;
end;
else do;
Category = put(SubCategory, 8. -l);
output;
end;
drop SubCategory v;
run;
Proc REPORT can produce the desired rendering of the data set.
proc report data=have;
columns category subcategory value;
define category / order noprint;
compute before category;
line category $200.;
endcomp;
run;
Some alternative renderings
proc print data=have;
by category;
id category;
var subcategory value;
run;
proc tabulate data=have;
class category subcategory;
var value;
table
category
* subcategory
,
value
;
run;
data haveR;
set have;
by category;
if first.category then output;
output;
run;
title "Report - indent";
proc report data=haveR;
column category subcategory cat value;
define category / order noprint;
define subcategory / display noprint;
define value / display;
define cat / computed style=[just=left] 'Category/hierarchy';
compute cat / length=200;
endcomp;
compute value;
if not missing(category) then do;
priorcategory = category;
cat = category;
value = .;
end;
else do;
cat = repeat('A0'x,3) || cats(subcategory);
end;
endcomp;
run;

How can I stack analysis variables on vertically in a PROC REPORT?

I am trying to stack multiple variables vertically in a PROC REPORT. I am tied to PROC REPORT over TABULATE or FREQ, so a solution using REPORT would be preferable.
I've tested out other solutions, but unable to find success using my data.
proc format library = library ;
value AGE
1 = '18 to 29'
2 = '30 to 45'
3 = '46 to 64'
4 = '65 and over'
9 = 'NA' ;
value SEX
1 = 'Male'
2 = 'Female'
9 = 'NA' ;
value Q16F
1 = 'EXCELLENT'
2 = 'VERY GOOD'
3 = 'GOOD'
4 = 'FAIR'
5 = 'POOR'
8 = 'DON''T KNOW'
9 = 'NA/REFUSED' ;
DATA CHSS2017_sashelp (keep = q16 sex age);
SET CHSS2017.CHSS2017_sashelp;
FORMAT q16 q16f.;
FORMAT sex SEX.;
FORMAT age AGE.;
RUN;
proc report data = CHSS2017_sashelp nowindows headline;
columns sex n, (q16);
define sex / group;
define q16 / across;
run;
The expected result would be a stacked REPORT table with multiple variables:
expected output
If you are fine with repeated headings/variable names then you can use two report procedures. See code below, I have used sample sas data and customized the formats a bit:
proc format ;
value AGE
1-10 = '1 to 10'
11-12 = '11 to 12'
13-High = '13 and over'
;
value $SEXv
'M' = 'Male'
'F' = 'Female'
;
value Q16F
1 = 'EXCELLENT'
2 = 'VERY GOOD'
3 = 'GOOD'
4 = 'FAIR'
5 = 'POOR'
8 = 'DON''T KNOW'
9 = 'NA/REFUSED' ;
run;
%macro RandBetween(min, max);
(&min + floor((1+&max-&min)*rand("uniform")))
%mend;
data class;
set sashelp.class;
q16 = %RandBetween(1, 9);
FORMAT q16 q16f.;
FORMAT sex $SEXv.;
FORMAT age AGE.;
run;
proc report data = class nowindows headline;
columns age n, (q16);
define age/ group;
define q16 / across;
run;
proc report data = class nowindows headline;
columns sex n, (q16);
define sex / group;
define q16 / across;
run;
the macro RandBetween is only for this code, you don't have to use it

How specify GBP currency in proc tabulate format

What is the format for GBP currency?
I would like to have the variable 'rent' to be displayed as £X in the below tabulate. What format should I put in the 'format' statement?
An example would be the equivalent of 'format=dollar12' that gives the USD currency. What would it be for GBP?
proc tabulate format=?;
var rent;
class bedrooms city;
table bedrooms, (city=' ' all='Total')*rent=' '*mean=' ' / box='Average Rent';
run;
Apply a format to the mean statistic using * f= NLMNLGBP.
From https://communities.sas.com/t5/General-SAS-Programming/How-do-I-specify-a-currency-format-and-a-comma-format-in-a-DATA/td-p/80230
applied NLMNLGBP. to the currency field, which formatted it as £1,672,349
Sample code
data have;
bedrooms=2; city='London'; rent=4500;
label rent = 'Rent';
format rent NLMNLGBP.;
run;
proc tabulate data=have;
class bedrooms city;
var rent;
table
bedrooms
,
(city=' ' all='Total')
* rent=' '
* mean=' ' * f=NLMNLGBP. %* <----- Happy brexiting ;
/
box='Average Rent'
;
run;

How do I use PROC EXPAND to fill in time series observations within a panel (longitudinal) data set?

I'm using this SAS code:
data test1;
input cust_id $
month
category $
status $;
datalines;
A 200003 ABC C
A 200004 DEF C
A 200006 XYZ 3
B 199910 ASD X
B 199912 ASD C
;
quit;
proc sql;
create view test2 as
select cust_id, input(put(month, 6.), yymmn6.) as month format date9.,
category, status from test1 order by cust_id, month asc;
quit;
proc expand data=test2 out=test3 to=month method=none;
by cust_id;
id month;
quit;
proc print data=test3;
title "after expand";
quit;
and I want to create a dataset that looks like this:
Obs cust_id month category status
1 A 01MAR2000 ABC C
2 A 01APR2000 DEF C
3 A 01MAY2000 . .
4 A 01JUN2000 XYZ 3
5 B 01OCT1999 ASD X
6 B 01NOV1999 . .
7 B 01DEC1999 ASD C
but the output from proc expand just says "Nothing to do. The data set WORK.TEST3 has 0 observations and 0 variables." I don't want/need to change the frequency of the data, just interpolate it with missing values.
What am I doing wrong here? I think proc expand is the correct procedure to use, based on this example and the documentation, but for whatever reason it doesn't create the data.
You need to add a VAR statement. Unfortunately, the variables need to be numeric. So just expand the month by cust_id. Then join back the original values.
proc expand data=test2 out=test3 to=month ;
by cust_id;
id month;
var _numeric_;
quit;
proc sql noprint;
create table test4 as
select a.*,
b.category,
b.status
from test3 as a
left join
test2 as b
on a.cust_id = b.cust_id
and a.month = b.month;
quit;
proc print data=test4;
title "after expand";
quit;

How can i print all the coefficient in one table?

I have a script in sas that output a lot's of tables of regression:
FILENAME RegProj URL "http://www.math.tau.ac.il/~liadshek/Long.txt" ;
DATA book;
length country $20;
INFILE RegProj firstobs=2 dlm=" " LRECL=131072 dsd truncover;
INPUT Country$ Year GDP_per_capita Infant_Mortality_Rate;
log_IMR = log(infant_mortality_rate);
log_gdp = log(GDP_per_capita);
RUN;
PROC reg data=book;
by year;
MODEL log_IMR = log_gdp;
output out = reg1;
run;
How can i print all the coefficient in one table?
I think you're looking for the outest option - try the following:
PROC reg data=book outest = reg_estimates;
by year;
MODEL log_IMR = log_gdp;
output out = reg1;
run;
This gives you all the regression coefficients in one table.