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.
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;
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.
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).
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?
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.
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;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Lock in the best rate now before the price increases on April 1.
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.