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 😀

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
  • 2031 views
  • 2 likes
  • 4 in conversation