- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
One and all,
I have the one dataset one variable id. its contains some observations.
data like this
data ds1;
input id @@;
datalines;
8 15 20 26 31 36 44 47 54 59 65 68 74 79 85 90 95 100
;
run;
50 and 75 are fixed values.
Form above dataset pick the nearst values.
1.74 is neartst value for id variable ( 75).
2.47 is nearst value for id variable (50).
note: the id variable values b/w 5 to 100.
plz help above problem.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, your question is really not clear. Where does 1.74/2.47 come from as all the values are decimal? What are these variables 75 and 50 you mention, there is only one variable called ID. Do you mean you want the value nearest to 50 and nearest to 75? Then something like (this creates two datasets, but you could do it in one, depends what you want out):
data ds1; input id @@; datalines; 8 15 20 26 31 36 44 47 54 59 65 68 74 79 85 90 95 100 ; run; data inter; set ds1; if id < 50 then tmp1=50-id; else tmp1=id-50; if id < 75 then tmp2=75-id; else tmp2=id-75; run; proc sort data=inter out=want50; by tmp1; run; proc sort data=inter out=want75; by tmp2; run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
HTH:
%let searchval=50;
data _null_;
set ds1 end=done;
retain result 100;
if abs(&searchval - id) < abs(&searchval - result) then result = id;
if done then call symput('result',put(result,4.));
run;
%put &result;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, your question is really not clear. Where does 1.74/2.47 come from as all the values are decimal? What are these variables 75 and 50 you mention, there is only one variable called ID. Do you mean you want the value nearest to 50 and nearest to 75? Then something like (this creates two datasets, but you could do it in one, depends what you want out):
data ds1; input id @@; datalines; 8 15 20 26 31 36 44 47 54 59 65 68 74 79 85 90 95 100 ; run; data inter; set ds1; if id < 50 then tmp1=50-id; else tmp1=id-50; if id < 75 then tmp2=75-id; else tmp2=id-75; run; proc sort data=inter out=want50; by tmp1; run; proc sort data=inter out=want75; by tmp2; run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
If your interest is pick the closest value of ID to 50 and 75 here is another way. Compare the pair of IDs that enclose either 50 or 75 and then choose the left or right of the pair based on closeness.
data have;
input id @@;
datalines;
8 15 20 26 31 36 44 47 54 59 65 68 74 79 85 90 95 100
;
run;
data want;
retain old ;
set have ;
if _n_ = 1 then old = id;
else do;
if (old < 50 < id) then do; val = ifn((50 - old) < (id - 50), old, id); output; end;
if (old < 75 < id) then do; val = ifn((75 - old) < (id - 75), old, id); output; end;
old = id;
end;
run;
proc print data = want;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Here's another approach:
proc sql;
select id as closest_to_50
from ds1
having abs(id-50)=min(abs(id-50));
select id as closest_to_75
from ds1
having abs(id-75)=min(abs(id-75));
quit;
The difference between this and @Kurt_Bremser's approach is that PROC SQL selects all IDs with the minimum distance from 50 or 75, respectively, not only the first one in the list. So, if you added the value 53 and a second occurrence of 47 to your sample list, PROC SQL would select 47, 47 and 53 as CLOSEST_TO_50. If your desired result in this case was only 47 and 53 (i.e. no duplicates), you could "select distinct id ..." to achieve this.