DATA Step, Macro, Functions and more

How to cap a curve by another curve

Accepted Solution Solved
Reply
New Contributor
Posts: 4
Accepted Solution

How to cap a curve by another curve

[ Edited ]

original_curve and cap_curve are inputs.

 

The original_curve is capped by the cap_curve, and the output is the capped_curve.

 

How to use SAS to create the capped_curve based on the original_curve and cap_curve?

 

cap_curve.png

 

Thanks!

data original_curve;
input x1 y1;
datalines;
0   0
200 100
300 200
run;

data cap_curve;
input x2 y2;
datalines;
0   50
130 50
250 210
300 210
;

data capped_curve;
input x3 y3;
datalines;
0   0
100 50
130 50
148 74
200 100
300 200
;

 


Accepted Solutions
Solution
‎03-04-2017 10:03 AM
Respected Advisor
Posts: 4,930

Re: How to cap a curve by another curve

Here is a way using proc expand:

 

data original_curve;
input x1 y1;
datalines;
0   0
200 100
300 200
run;

data cap_curve;
input x2 y2;
datalines;
0   50
130 50
250 210
300 210
;

data all_c;
merge 
    original_curve(rename=x1=x) 
    cap_curve(rename=x2=x);
by x;
run;

proc expand data=all_c out=all_int;
id x;
convert y1 y2 / method=join;
run;

data capped_curve;
retain xp yp1 yp2;
set all_int(rename=(x=xc y1=yc1 y2=yc2));
if _n_ > 1 then do;
    if (yc1>yc2) ne (yp1>yp2) then do;
        a = (yc2-yc1) / (yc2-yc1+yp1-yp2);
        x3 = a*xp + (1-a)*xc;
        y3 = a*yp1 + (1-a)*yc1;
        output;
        end;
    end;
x3 = xc;
y3 = min(yc1, yc2);
output;
xp = xc;
yp1 = yc1;
yp2 = yc2;
keep x3 y3;
run;
PG

View solution in original post


All Replies
Super User
Posts: 19,851

Re: How to cap a curve by another curve

Change your CAP curve to a different format:

 

start end max_value

 

Then merge second table on the condition that

 

Proc sql;

create table want as 

select a.x1, min(b.max_value, a.y1) as capped_value

from tableA as a

left join tableB as b on 

A.x1 between start and end;

quit;

 

I'm not sure how you determined the values to belong to the third table but this should help you get the idea. 

Solution
‎03-04-2017 10:03 AM
Respected Advisor
Posts: 4,930

Re: How to cap a curve by another curve

Here is a way using proc expand:

 

data original_curve;
input x1 y1;
datalines;
0   0
200 100
300 200
run;

data cap_curve;
input x2 y2;
datalines;
0   50
130 50
250 210
300 210
;

data all_c;
merge 
    original_curve(rename=x1=x) 
    cap_curve(rename=x2=x);
by x;
run;

proc expand data=all_c out=all_int;
id x;
convert y1 y2 / method=join;
run;

data capped_curve;
retain xp yp1 yp2;
set all_int(rename=(x=xc y1=yc1 y2=yc2));
if _n_ > 1 then do;
    if (yc1>yc2) ne (yp1>yp2) then do;
        a = (yc2-yc1) / (yc2-yc1+yp1-yp2);
        x3 = a*xp + (1-a)*xc;
        y3 = a*yp1 + (1-a)*yc1;
        output;
        end;
    end;
x3 = xc;
y3 = min(yc1, yc2);
output;
xp = xc;
yp1 = yc1;
yp2 = yc2;
keep x3 y3;
run;
PG
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 2 replies
  • 196 views
  • 1 like
  • 3 in conversation