BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Miracle
Barite | Level 11

Dear All,

How do I flag=Y when varX is closet to one by id and varZ please?

Thanks in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26
data two;
     set one;
     distance = abs(varX - 1);
run;
proc summary data=two nway;
     class id varz;
     var distance;
    output out=_stats_ min=min_distance;
run;
data want;
     merge two _stats_;
     by id varz;
     if distance=min_distance than flag="Y";
run;
--
Paige Miller

View solution in original post

8 REPLIES 8
PeterClemmensen
Tourmaline | Level 20

Show us your data 🙂

PaigeMiller
Diamond | Level 26

@Miracle wrote:

 

How do I flag=Y when varX is closet to one by id and varZ please?


Please explain this further. Provide more details. Show us an example.

--
Paige Miller
Miracle
Barite | Level 11

Thanks @PeterClemmensen  and @PaigeMiller for your quick response.
Take this data for example please.
So I need to flag=Y when varX is closest to one by id and varZ.
Thanks in advance.

id  varX varZ flag
1 1 A Y
1 50 A  
1 1 B Y
1 4 B  
1 3 C  
1 2 C Y
2 10 A  
2 3 A Y
2 3 A Y
2 3 B  
2 4 B  
2 -1 B Y
2 3 C Y
2 6 C  
PaigeMiller
Diamond | Level 26
data two;
     set one;
     distance = abs(varX - 1);
run;
proc summary data=two nway;
     class id varz;
     var distance;
    output out=_stats_ min=min_distance;
run;
data want;
     merge two _stats_;
     by id varz;
     if distance=min_distance than flag="Y";
run;
--
Paige Miller
PeterClemmensen
Tourmaline | Level 20

My 2 cents. 

 

Is there a reason why the row 

 

2 3 B  

 

should not be flagged?

 

data have;
input id varX varZ $;
datalines;
1 1  A
1 50 A
1 1  B
1 4  B
1 3  C
1 2  C
2 10 A
2 3  A
2 3  A
2 3  B
2 4  B
2 -1 B
2 3  C
2 6  C
;


data want(drop=mdist);
   do _N_ = 1 by 1 until (last.varZ);
      set have;
      by id varZ;
      mdist = min(mdist, abs(1 - varX));
   end;

   do _N_ = 1 to _N_;
      set have;
      flag = ifc(abs(1 - varX) = mdist, "Y", "");
      output;
   end;
run;

Result

 

id varX varZ flag 
1  1    A    Y 
1  50   A      
1  1    B    Y 
1  4    B      
1  3    C      
1  2    C    Y 
2  10   A      
2  3    A    Y 
2  3    A    Y 
2  3    B    Y 
2  4    B      
2  -1   B    Y 
2  3    C    Y 
2  6    C      
Miracle
Barite | Level 11

Thanks @PeterClemmensen  for the sharp eye.
You are absolutely right! 

gamotte
Rhodochrosite | Level 12

Hello,

 

A solution with proc sql :

proc sql noprint;
    CREATE TABLE want AS
    SELECT *, CASE WHEN abs(varX-1)=min(abs(varX-1)) THEN "Y" END AS Flag
    FROM have
    GROUP BY id, varZ
    ;
quit;
Miracle
Barite | Level 11

Thanks @PaigeMiller@PeterClemmensen  and @gamotte  for all your solutions! Much appreciate it 😀

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 657 views
  • 2 likes
  • 4 in conversation