This is quick and dirty so some optimization could probably be done but hopefully this gets you going: A couple of notes: 1) The card statements are just getting test data in. You need a table with all your ids present and all the months you want to use present so the sql can make the cartesian product between the ids and months. 2) Some of the sql steps can be combined, but I left them separate so it was easier to see what was happening. infile cards dlm=','; input pid month; cards; 1, 3 2, 5 4, 6 4, 1 5, 12 1, 3 8, 5 4, 6 4, 2 5, 12 ; run; data all; infile cards ; input pid; cards; 1 2 4 3 4 5 5 6 7 8 8 9 2 10 ; run; data mnthin; infile cards; input month; cards; 1 2 3 4 4 4 5 5 6 7 8 8 9 10 11 12 ; run; proc sql; create table cnts as select pid, month, count(*) as cnt from in group by pid, month ; create table ids as select distinct pid from all ; create table mnth as select distinct month from mnthin ; create table cartesian as select a.pid, b.month from ids as a , mnth as b ; create table out1 as select a.pid, a.month, coalesce(b.cnt,0) as cnt from cartesian as a left join cnts as b on a.pid =b.pid and a.month = b.month order by pid, month ; quit; Hope this helps! EJ data out2; set out1; by pid month; if first.pid then do; vis_jan = 0; vis_feb = 0; vis_mar = 0; vis_apr = 0; vis_may = 0; vis_jun = 0; vis_jul = 0; vis_aug = 0; vis_sep = 0; vis_oct = 0; vis_nov = 0; vis_dec = 0; end; select (month); when (1) vis_jan = cnt; when (2) vis_feb = cnt; when (3) vis_mar = cnt; when (4) vis_apr = cnt; when (5) vis_may = cnt; when (6) vis_jun = cnt; when (7) vis_jul = cnt; when (8) vis_aug = cnt; when (9) vis_sep = cnt; when (10) vis_oct = cnt; when (11) vis_nov = cnt; when (12) vis_dec = cnt; end; retain vis: ; drop cnt month; if last.pid then output; run;
... View more