Ваш подход должен будет использовать такую конструкцию, как
COUNT(distinct CASE when year=<year> and agecat=1 then id else . end) as year_<year>
С точки зрения кодирования, это, вероятно, неправильный подход, особенно если вы хотите, чтобы для каждого agecat
имелось различное число.Вам понадобится одно выражение для каждой комбинации year
и agecat
.
Преобразование значений года из положения в столбце в имя столбца - это сводная точка (и изменение структуры данных) изданные к метаданным и приводит к головным болям.Существуют такие процедуры, как PROC TABULATE
и PROC REPORT
для создания выходных данных, которые отображают категориальные данные в столбчатой форме.PROC TRANSPOSE
также можно использовать для выполнения этих опорных точек.
Пример кода:
ods _all_ close;
ods html5 path='c:\temp' file='catcounts.html';
options nocenter nodate nonumber;
data have;
do id = 1 to 1000;
do year = 2007 to 2014;
if ranuni(123) < 0.75 then continue;
agecat = ceil(4*ranuni(123));
output;
end;
end;
run;
* ugly, expression pivot;
proc sql;
create table want(label="Unique ID count by year") as
select
count (distinct case when year=2007 and agecat=1 then id else . end) as yr_2007_age1_idcount,
count (distinct case when year=2008 and agecat=1 then id else . end) as yr_2007_age2_idcount,
count (distinct case when year=2009 and agecat=1 then id else . end) as yr_2007_age3_idcount
/* potentially many more */
from have;
* clean, categorical counts;
proc sql;
create table counts(label="Unique ID count by year and agecat") as
select
year, agecat, count(distinct id) as idCount
from have
group by year, agecat;
proc print noobs data=counts;
title "PRINT: Categorical counts results - output limited with where statement";
where year between 2010 and 2015 and agecat in (1,2);
run;
* pivot categorical, limited to agecat=1;
proc transpose data=counts out=counts_agecat1 prefix=year_;
id year;
var idCount;
where agecat=1;
quit;
proc print noobs data=counts_agecat1;
title "PRINT: ID Counts for agecat=1";
title2 "Pivot made with TRANSPOSE and limited with where statement";
run;
proc transpose data=counts out=counts_wide prefix=count_ delimiter=_;
id year agecat;
var idCount;
where agecat in (1,2);
quit;
proc print noobs data=counts_wide;
title "PRINT: ID counts for each year and agecat";
title2 "Pivot made with TRANSPOSE and ID year agecat and limited with where statement";
run;
proc tabulate data=counts;
title "Tabulate: Display the pre-computed categorical counts";
class year agecat;
var idCount;
table year='',agecat*idCount=''*sum=''*f=best12./nocellmerge;
run;
proc tabulate data=counts;
title "Tabulate: Display the pre-computed categorical counts";
class year agecat;
var idCount;
table agecat,year=''*idCount=''*sum=''*f=best12./nocellmerge;
run;
proc report data=counts;
title "Report: Display the pre-computed categorical counts";
column year agecat,idCount ;
define year / group;
define agecat / across;
run;
ods _all_ close;