To re-formulate your requirement: I want to select rows for the id, whose id have NEVER a missing "type" for "visit_year" between 2007 to 2011 AND for which there is at least one row per year.
I assume there could also be multiple visit dates (rows) for an ID in a single year.
Below code basically using what @Kurt_Bremser proposed with some tweaks to check the type variable and ensuring that there can't be an out of array subscript condition. I've also amended your sample data slightly to make it a bit more representative for how I assume your real data looks like (=multiple rows per year for an id - of which one row could have a missing type).
data have;
infile datalines dsd truncover;
input id type visit_date :yymmdd10.;
format visit_date yymmdd10.;
datalines;
1,1,2007-01-01
1,1,2007-05-01
1,2,2008-01-02
1,2,2009-01-03
1,3,2010-01-04
1,5,2011-01-05
9,1,2007-01-01
9,1,2007-05-01
9,.,2007-06-01
9,2,2008-01-02
9,2,2009-01-03
9,3,2010-01-04
9,5,2011-01-05
2,1,2008-01-01
2,2,2008-01-02
2,2,2009-01-03
2,3,2010-01-04
2,5,2011-01-05
2,5,2012-01-05
3,2,2007-01-09
3,.,2008-01-10
3,2,2009-01-11
3,.,2010-01-12
3,.,2011-01-12
4,.,2007-01-10
4,3,2008-01-11
4,1,2009-01-12
5,2,2007-01-11
5,2,2008-01-12
5,2,2009-01-10
5,2,2010-01-11
6,2,2008-01-12
6,1,2009-01-10
6,.,2010-01-11
;
proc sort data=have;
by id;
run;
data want;
array _y{2007:2011};
call missing(of _y[*]);
do until (last.id);
set have;
by id;
if 2007<=year(visit_date)<=2011 then
do;
if missing(type) then _y{year(visit_date)} = 0;
else _y{year(visit_date)} = _y{year(visit_date)} ne 0;
end;
end;
do until (last.id);
set have;
by id;
if sum(of _y:) = 5 then output;
end;
drop _y:;
run;
proc print data=want;
run;
... View more