Hello there,
I'm currently analyzing aggregate data using proc SQL and I've encountered an issue.
Is there a way to look at a crosstab with a repetitive row value as a column.
e.g. Dataset:
OBS REGION YEAR SEX COUNT
1 1 2016 M 12
2 2 2016 M 5
3 1 2017 M 10
4 2 2017 M 8
5 1 2018 M 6
6 2 2018 M 15
... ... ... ... ...
I would like to create a table of male count by region and year. However I would like to have the year as a column to get something like this:
COUNT
REGION 2016 2017 2018
1 12 10 6
2 5 8 15
Thank you!
data have;
input OBS REGION YEAR MALE FEMALE TOTAL;
cards;
1 1 2016 12 5 17
2 2 2016 15 7 22
3 1 2017 10 4 14
4 2 2017 8 4 12
5 1 2018 6 5 11
6 2 2018 15 10 25
;
proc tabulate data=have;
class region year ;
var male female;
table region=' ',year=' '*(male female)/box='REGION' ;
keylabel sum=' ';
run;
Welcome to the SAS Community 🙂
Use PROC FREQ and do something like this
data have;
input OBS REGION YEAR SEX $ COUNT;
datalines;
1 1 2016 M 12
2 2 2016 M 5
3 1 2017 M 10
4 2 2017 M 8
5 1 2018 M 6
6 2 2018 M 15
;
proc freq data=have;
tables region*year;
weight count;
run;
Hello,
There might be a lot of ways to achieve what you need here. What I do is broken down into 3 steps.
**Step 1. proc sql group **;
Group by region and year, since you are interested in the count for each region by year.
proc sql;
create table aggregate as
select region, year, count
from dataset
where sex='M'
group by region, year;
quit;**Step 2. proc transpose **;
proc transpose data=aggregate out=aggregate2;
var count;
id year;
by region;
run;
**Step 3. data-step clean-up **;
data want;
set aggregate2;
drop _NAME_;
rename
_2016 = cnt_2016
_2017 = cnt_2017
_2018 = cnt_2018
......
;
run;The dataset named 'want' should be what you are looking for.
data have;
input OBS REGION YEAR SEX $ COUNT;
datalines;
1 1 2016 M 12
2 2 2016 M 5
3 1 2017 M 10
4 2 2017 M 8
5 1 2018 M 6
6 2 2018 M 15
;
proc tabulate data=have;
class region year;
var count;
table region=' ',count*year=' '/box='REGION' ;
keylabel sum=' ';
run;
Thank you for your solution. Do you know if I can still use this function if I want to make a crosstab with more than two variables? I've tried it and I get an error.
Ultimately, what I would like to do is a table like this:
2016 2017 2018
REGION MALE FEMALE MALE FEMALE MALE FEMALE
1 12 ... 10 ... 6 ...
2 5 ... 8 ... 15 ...
Thank you again.
Sure.
data have;
input OBS REGION YEAR SEX $ COUNT;
datalines;
1 1 2016 M 12
2 2 2016 M 5
3 1 2017 M 10
4 2 2017 M 8
5 1 2018 M 6
6 2 2018 M 15
;
proc tabulate data=have;
class region year sex;
var count;
table region=' ',year=' '*sex=' '*count=' '/box='REGION' ;
keylabel sum=' ';
run;
But that would only work with record-level data (where each row equals one individual). I'm using aggregated data.
So my database looks like this:
OBS REGION YEAR MALE_Count FEMALE_Count TOTAL
1 1 2016 12 5 17
2 2 2016 15 7 22
3 1 2017 10 4 14
4 2 2017 8 4 12
5 1 2018 6 5 11
6 2 2018 15 10 25
It was probably unclear in my first question.
Thanks
Then maybe consider a single proc transpose:
*Assuming you only care about the male counts*;
proc transpose data=dataset out=want;
var male_count;
id year;
by region;
run;
***Rename variables and delete _NAME_;
proc datasets library=work;
modify want;
rename _2016 = cnt_2016;
rename _2017 = cnt_2017;
rename _2018 = cnt_2018;
data have;
input OBS REGION YEAR MALE FEMALE TOTAL;
cards;
1 1 2016 12 5 17
2 2 2016 15 7 22
3 1 2017 10 4 14
4 2 2017 8 4 12
5 1 2018 6 5 11
6 2 2018 15 10 25
;
proc tabulate data=have;
class region year ;
var male female;
table region=' ',year=' '*(male female)/box='REGION' ;
keylabel sum=' ';
run;
It works.
Thank you very much Ksharp!
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!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.