Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Home
- /
- Programming
- /
- Programming
- /
- Estimate inflection point for 2 linear lines

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

☑ This topic is **solved**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 08-21-2023 03:01 PM
(342 views)

I have a data where the slope changes at a certain point. How do you find that point of inflection for the two linear lines? I think PROC NLIN would work but I can't get it to run.

Sample code is given below as I cannot share my data. The point of inflection is 50.

```
DATA data1;
do i=1 to 1000;
x=rand("Integer", 1, 50);
Y=3 + 6*x + rannor(345);
drop i;
OUTPUT;
end;
RUN;
DATA data2;
do i=1 to 1000;
x=rand("Integer", 50, 100);
Y=2 + 8*x + rannor(345);
drop i;
OUTPUT;
end;
RUN;
data full; set data1 data2;run;
proc nlin data=full;
parms alpha1=.45 beta1=.05 alpha2=.45 beta2=.05;
x0=5*beta1/alpha1;
model y = (x <x0)*(alpha1+beta1*x) +
(x>=x0)*(alpha2+beta2*x);
FILE log;put / x0= ;
output out=b predicted=yp;
run;
```

1 ACCEPTED SOLUTION

Accepted Solutions

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Hello @PamG ,

If your only interest is to know about the inflection point ,

then you can use PROC UCM (SAS/ETS) for structural break detection in a univariate time series.

I use your variable X as a time indicator. This is possible because in your sample data the X-values are equally spaced (fixed width interval).

Not sure how close X is to a real time series in your actual data (?).

```
DATA data1;
do i=1 to 1000;
x=rand("Integer", 1, 50);
Y=3 + 6*x + rannor(345);
drop i;
OUTPUT;
end;
RUN;
DATA data2;
do i=1 to 1000;
x=rand("Integer", 50, 100);
Y=2 + 8*x + rannor(345);
drop i;
OUTPUT;
end;
RUN;
data full; set data1 data2; run;
proc sort data=full; by x; run;
proc sgplot data=full;
scatter x=x y=y;
run;
/* Accumulating Transactional Data into Time Series Data */
/* Goal is to get Only 1 observation per unique value of X */
proc timeseries data=full out=tsfull;
id x interval=day
accumulate=median
setmiss=0
;
var y;
run;
proc sgplot data=tsfull;
scatter x=x y=y;
run;
ods trace off;
/* Detection of Level Shift by unobserved components model (UCM). */
/* (The UCMs are also called structural models in the time series literature.) */
/* You can check for breaks in the level by using the CHECKBREAK option in the LEVEL statement. */
/* The following statements fit a simple locally constant level plus constant slope */
/* plus error model to the series: */
ODS EXCLUDE EstimationSpan ForecastSpan InitialParameters FitSummary
ParameterEstimates FitStatistics ComponentSignificance
TrendInformation Forecasts ForecastsOnlyPlot ;
ODS OUTPUT OutlierSummary=work.OutlierSummary;
proc ucm data=tsfull;
id x interval=day;
model y;
irregular;
/* The fitted trend is nearly linear, */
/* So I fix fix the level and/or slope variance components to zero */
/* (via the VARIANCE=0 and NOEST options on the LEVEL and/or SLOPE statements) */
level variance=0 noest /* plot=smooth */ checkbreak;
slope variance=0 noest;
*estimate;
*forecast plot=decomp;
run;
data _NULL_;
set work.OutlierSummary;
file print;
put 'inflection point is at ' time= 12.;
run;
/* end of program */
```

BR,

Koen

9 REPLIES 9

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

I think PROC NLIN would work but I can't get it to run.

What is wrong with your code?

--

Paige Miller

Paige Miller

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

@PamG wrote:

Thank you. In the future, key information like this should be in your first message.

This discusses the error message that says the Hessian is singular: https://communities.sas.com/t5/Statistical-Procedures/Problem-in-Proc-NLIN-The-approximate-Hessian-i... There may be other similar discussions here in the SAS communities, and you should search for them.

--

Paige Miller

Paige Miller

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Hello @PamG ,

If your only interest is to know about the inflection point ,

then you can use PROC UCM (SAS/ETS) for structural break detection in a univariate time series.

I use your variable X as a time indicator. This is possible because in your sample data the X-values are equally spaced (fixed width interval).

Not sure how close X is to a real time series in your actual data (?).

```
DATA data1;
do i=1 to 1000;
x=rand("Integer", 1, 50);
Y=3 + 6*x + rannor(345);
drop i;
OUTPUT;
end;
RUN;
DATA data2;
do i=1 to 1000;
x=rand("Integer", 50, 100);
Y=2 + 8*x + rannor(345);
drop i;
OUTPUT;
end;
RUN;
data full; set data1 data2; run;
proc sort data=full; by x; run;
proc sgplot data=full;
scatter x=x y=y;
run;
/* Accumulating Transactional Data into Time Series Data */
/* Goal is to get Only 1 observation per unique value of X */
proc timeseries data=full out=tsfull;
id x interval=day
accumulate=median
setmiss=0
;
var y;
run;
proc sgplot data=tsfull;
scatter x=x y=y;
run;
ods trace off;
/* Detection of Level Shift by unobserved components model (UCM). */
/* (The UCMs are also called structural models in the time series literature.) */
/* You can check for breaks in the level by using the CHECKBREAK option in the LEVEL statement. */
/* The following statements fit a simple locally constant level plus constant slope */
/* plus error model to the series: */
ODS EXCLUDE EstimationSpan ForecastSpan InitialParameters FitSummary
ParameterEstimates FitStatistics ComponentSignificance
TrendInformation Forecasts ForecastsOnlyPlot ;
ODS OUTPUT OutlierSummary=work.OutlierSummary;
proc ucm data=tsfull;
id x interval=day;
model y;
irregular;
/* The fitted trend is nearly linear, */
/* So I fix fix the level and/or slope variance components to zero */
/* (via the VARIANCE=0 and NOEST options on the LEVEL and/or SLOPE statements) */
level variance=0 noest /* plot=smooth */ checkbreak;
slope variance=0 noest;
*estimate;
*forecast plot=decomp;
run;
data _NULL_;
set work.OutlierSummary;
file print;
put 'inflection point is at ' time= 12.;
run;
/* end of program */
```

BR,

Koen

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

On top of PROC UCM post above ,

see also :

Segmented regression models in SAS

By Rick Wicklin on The DO Loop December 14, 2020

https://blogs.sas.com/content/iml/2020/12/14/segmented-regression-sas.html

BR,

Koen

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thanks Koen. I do not have a time series data and I do not have a jump in the line. I am so sorry but I do not know how to create sample datasets to show continuous lines but with different slopes. I have (y,x) points and I would like to know where the joint point is that has no breaks.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

@PamG wrote:

I have a data where the slope changes at a certain point. How do you find that point of inflection for the two linear lines?

<Pendantic mode=on>

"Linear Lines" have no inflection point where the slope changes. Curves may.

<Pendatic mode=off>

Are you assuming both of your curves have inflection points at the same value? That may be pretty broad assumption.

Are you using a different definition of inflection other than a point on the curve where the slope changes sign?

BTW, if your data is so sensitive that a group of x,y pairs with no other identification causes concerns then perhaps you shouldn't be asking any questions on an open forum.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Hello @PamG,

Another option: Try PROC FASTCLUS to get a first estimate of the point of inflection and then use PROC ROBUSTREG for fine-tuning (see the proportions of outliers in the "Diagnostic Summary" table of the output) and estimation of the regression coefficients.

```
proc fastclus data=full out=clust maxclusters=2 maxiter=100;
var x y;
run;
proc means data=clust;
class cluster;
var x;
run;
proc sort data=clust;
by cluster;
run;
proc robustreg data=clust method=lts seed=2718;
by cluster;
model y=x;
run;
```

Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

**If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. **

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.