DATA Step, Macro, Functions and more

Running a function for each unique value

Reply
Occasional Contributor
Posts: 19

Running a function for each unique value

Hello,

I am wondering if it's possible to check whether a condition is satisfied for every unique ID in my dataset. For example,

ID1 BMI
ID1 CHOL
ID1 GLUCOSE
ID1 BP
ID2 CHOL
ID2 GLUCOSE

So for ID1, their biometrics screenings would be complete (I was thinking of creating a new variable called biometrics that equals 1 if all 4 are there). However, for ID2, since the person only has two of the 4, biometrics would be 0, indicating that the individual is not up-to-date with his biometrics. Is this at all possible? Thanks.
Super User
Posts: 17,912

Re: Running a function for each unique value

Can you have multiple entries for a particular screen? Ie BMI is collected twice?

PROC Star
Posts: 7,364

Re: Running a function for each unique value

Are they all on one record for a given ID, or on multiple records? Regardless, what is/are the variables called?

 

Art, CEO, AnalystFinder.com

Occasional Contributor
Posts: 19

Re: Running a function for each unique value

[ Edited ]

Hi Reeza. So my dataset is actually a lot more confusing than the example I provided. There's a difference between BMI_current and BMI, but I just wanted to get help on a more general level and adjust the code as needed. Let's say BMI isn't collected twice.

Occasional Contributor
Posts: 19

Re: Running a function for each unique value

Hi art, they are on multiple records. The ID variable is ID and the screening variable is called ActionName.
PROC Star
Posts: 7,364

Re: Running a function for each unique value

I think you are asking if you can do something like:

data have;
  input id ActionName $;
  cards;
1 BMI
1 CHOL
1 GLUCOSE
1 BP
2 BMI
2 CHOL
3 BMI
3 CHOL
3 GLUCOSE
3 OTHER
4 BMI
4 CHOL
4 GLUCOSE
4 BP
;
data want;
  do until(last.id);
    set have;
    by id;
    if first.id then biometrics=0;
    if ActionName='BMI' then biometrics=sum(biometrics,.0001);
    else if ActionName='CHOL' then biometrics=sum(biometrics,.0010);
    else if ActionName='GLUCOSE' then biometrics=sum(biometrics,.0100);
    else if ActionName='BP' then biometrics=sum(biometrics,.1000);
    if last.id then if biometrics eq .1111 then output /*or something else*/ ;
  end;
run;

Art, CEO, AnalystFinder.com

 

Valued Guide
Posts: 765

Re: Running a function for each unique value

[ Edited ]

Hi, another idea ...

 

data have;
input id x :$7. @@;
datalines;
1 BMI 1 CHOL 1 GLUCOSE 1 BP
2 BMI 2 CHOL 3 BMI 3 CHOL
3 GLUCOSE 3 OTHER 4 BMI 4 CHOL
4 GLUCOSE 4 BP 4 OTHER 4 DUDE
;

 

* find maximum number of observations within an ID;

proc sql noprint;
select max(count) into :max from
(select count(*) as count from have group by id);
quit;

 

* reshape data, one observation per ID;

proc summary data=have nway;
class id;
output out=have2 (drop=_: ) idgroup(out[&max] (x)=);
run;

 

data want;
set have2;
array x_(&max);
all4 = ('BMI' in x_) & ('CHOL' in x_) & ('GLUCOSE' in x_) & ('BP' in x_);
run;

 

DATA SET: want

id    x_1    x_2       x_3      x_4       x_5     x_6     all4

 1    BMI    CHOL    GLUCOSE    BP                          1
 2    BMI    CHOL                                           0
 3    BMI    CHOL    GLUCOSE    OTHER                       0
 4    BMI    CHOL    GLUCOSE    BP       OTHER    DUDE      1

 

Or, using a bit of Art's approach ...

 

data want (keep=id all4);
array x_(50) $7;
do j=1 by 1 until(last.id);
  set have;
  by id;
  x_(j) = x;
end;
all4 = ('BMI' in x_) & ('CHOL' in x_) & ('GLUCOSE' in x_) & ('BP' in x_);
run;

 

DATA SET: want

id    all4

 1      1
 2      0
 3      0
 4      1
Super User
Posts: 9,687

Re: Running a function for each unique value

data have;
input id $ x $ ;
cards;
ID1 BMI
ID1 CHOL
ID1 GLUCOSE
ID1 BP
ID2 CHOL
ID2 GLUCOSE
;
run;
proc sql;
select *,case when count(distinct x)=4 then 1 else 0 end as flag
 from have
  group by id;
quit;
Ask a Question
Discussion stats
  • 7 replies
  • 111 views
  • 1 like
  • 5 in conversation