BookmarkSubscribeRSS Feed
Vic3
Fluorite | Level 6

In my example below the equation is simplified and number of constants is reduced for clarity. I'm using SAS 9.4 x64.

Simple exponential decay function: C=Co*EXP(-k*time)

For any given Co there are multiple “time - C” data pairs (each Co representing a separate experiment). Namely:

Co        time      C

5          0          5

5          1          3.1

5          2          1.8

…         …         …

8          0          8

8          1          5.9

8          2          4.4

…         …         …

 

I would like to generate a series of regressions, one for each value of Co.

 

When I manually type in Co value into the code, for example, C=5*EXP(-k*time), everything works fine.

ods graphics on / width=640PX height=480PX;
proc nlin data=example plots;
	parameters k=0.5;
	where Co = 5;
	model C = 5 * EXP(-k*time);
run;
ods graphics off;

I receive a graph of C vs time with raw data and a regression curve and correct numerical output (parameter estimates, etc.). Obviously, I get one regression at a time.

 

When I add Co as a variable (below), numerical output is identical to the previous approach, but strangely the graphs depict Co vs time instead (which happens to be a vertical line).

ods graphics on / width=640PX height=480PX;
proc nlin data=example plots;
	parameters k=0.5;
	by Co;
	model C = Co * EXP(-k*time);
run;
ods graphics off;

Is there a simple way to fix this? I need to examine the graphs with data and regression line as well as numerical output. I don’t want to do one regression at a time, there are too many.

 

Thank you.

6 REPLIES 6
Rick_SAS
SAS Super FREQ

Typically, C0 is a parameter that the model estimates. 

This is not a nonlinear model; it is log-linear, which means

Take log of both sides:

log(Y) = log(C0) - K*T

Define Z = log(Y). Then perform a linear regression for

MODEL Z = T;

and use the Intercept and estimate of the T variable to form the estimate for your exponential model.

 

If, for some reason, you want to specify C0, then define W = log(Y/C0) and solve the no-intercept linear system

MODEL W = T / NOINT;

Vic3
Fluorite | Level 6

Thank you.
Co has to be specified. Unfortunately, I can't turn it into a linear model either. I simplified the equation for clarity.
I just want to loop through subsets of data, generating a sequence of equations.

FreelanceReinh
Jade | Level 19

Hi @Vic3,

 

It's strange that there should be no way to tell PROC NLIN that Co is a constant and not a parameter. A workaround that I've just tested is: Create the BY variable as a character variable (say, Coc) and adapt the MODEL statement correspondingly:

model C = input(Coc,32.)*EXP(-k*time);

or leave the MODEL statement unchanged and insert the definition of Co before the MODEL statement:

Co=input(Coc,32.);
model C = Co*EXP(-k*time);

This solution seems to be faster than a macro implementing your WHERE approach in a %DO loop (not surprisingly).

 

Vic3
Fluorite | Level 6

That works to produce numerical output, but not graphs. SAS finds parameters correctly either way, but for some reason plots time vs Co (a constant) instead of C vs time. Should plot statement be modified?

FreelanceReinh
Jade | Level 19

I had tested my code and it produced exactly the same correct five graphs as with a WHERE condition -- without changing your code w.r.t. plot requests.

 

The key is that the input dataset does not contain a numeric variable Co (unless it is not used in the MODEL statement anyway). I suspect that you didn't drop it from your input dataset.

 

Please note that in my first suggestion (model C = input(Coc,32.)*EXP(-k*time);) a variable Co is not even mentioned, so it's impossible that SAS "plots time vs Co (a constant)."

 

In my second suggestion, Co is defined only in the PROC NLIN step. If it is not contained in the input dataset (this is important), the procedure will not treat this variable as a parameter.

 

Rick_SAS
SAS Super FREQ

Regression procedures assume that a column in the data set that is involved in the model is a variable. In your case, you have a variable that has no variance, it is a constant.

 

One way to handle this problem is to transform the variables (rescale) to incorporate the constant. For example, 

data Have;
input Co        time      C;
datalines;
5          0          5
5          1          3.1
5          2          1.8
5          3          0.3
8          0          8
8          1          5.9
8          2          4.4
8          3          3.2
;

proc sort data=Have;
by Co Time;
run;

data Want;
set Have;
by Co; 
ScaledC = C / Co;
run;

proc nlin data=Want plots=Fit;
	parameters k=0.5;
	by Co;
	model ScaledC = EXP(-k*time);
run;

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 6 replies
  • 713 views
  • 3 likes
  • 3 in conversation