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 😀

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

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