Good Morning, my name is Thiago and I'm trying to do an interactive procedure to calculate real base and ceiling temperatures of beta model in tree growth.
I used a procedure described in an article (image below), however I do not understand the way it is done, since my SAS code is showing errors.
SAS code:
data temp;
k=(Tc-To)/(To-Tb);
l=(0.05**2)*(To-Tb)*((Tc-To)**k);
do i=0 to 10;
L[i+1]=l/(((Tc-Tb)**(k+1))*((1-L[i])**k));
U[i+1]=(l/(((Tc-Tb)**(k+1))*((1-U[i])))**(1/k);
output;
end;
My data "temp" has the To, Tb and Tc values for the iteractive procedure.
Someone could help about that?
Thanks
The obvious error in your code is that you have not assigned values to variables Tc To or Tb.
But for your future reference, you can't just simply say "SAS code is showing errors". You MUST show us the log from SAS, with nothing chopped out, so that we can see the code in the log plus all WARNINGs NOTEs and ERRORs for the step that has the problem. When providing the log, it is critical that you maintain the formatting of the log so we can see it exactly as SAS showed it to you, making it easier for us to use. To maintain the formatting of the log, click on the </> icon and paste the log as text into the window that appears. DO NOT SKIP THIS STEP.
176 data temp; 177 k=(Tc-To)/(To-Tb); 178 l=(0.05**2)*(To-Tb)*((Tc-To)**k); 179 do i=0 to 10; 180 L[i+1]=l/(((Tc-Tb)**(k+1))*((1-L[i])**k)); ERROR: Undeclared array referenced: l. ERROR: Undeclared array referenced: l. ERROR: Variable l has not been declared as an array. ERROR: Variable l has not been declared as an array. 181 U[i+1]=(l/(((Tc-Tb)**(k+1))*((1-U[i])))**(1/k); - 79 ERROR: Undeclared array referenced: U. ERROR: Undeclared array referenced: U. ERROR: Variable U has not been declared as an array. ERROR 79-322: Expecting a ). 182 output; ERROR: Variable U has not been declared as an array. 183 end;
I'm sorry, but I forgot to share the SAS log.
Thanks PaigeMiler.
In addition to the fact that I mentioned that you have not assigned values to the variables, you also need ARRAY statements to declare that L and U are arrays.
It will be something like this:
data temp; k=(Tc-To)/(To-Tb); l=(0.05**2)*(To-Tb)*((Tc-To)**k); array L{i+1}=l/(((Tc-Tb)**(k+1))*((1-L{i}**k)); do i=0 to 10 by 1; end; run;
The error in log still occured:
269 data temp; 270 k=(Tc-To)/(To-Tb); 271 l=(0.05**2)*(To-Tb)*((Tc-To)**k); 272 array L{i+1}=l/(((Tc-Tb)**(k+1))*((1-L{i}**k)); - 124 - 22 76 ERROR 124-185: The variable L has already been defined. ERROR 22-322: Syntax error, expecting one of the following: an integer constant, *. ERROR 76-322: Syntax error, statement will be ignored. 273 do i=0 to 10 by 1; 274 end; 275 run; NOTE: The SAS System stopped processing this step because of errors. WARNING: The data set WORK.TEMP may be incomplete. When this step was stopped there were 0 observations and 6 variables. WARNING: Data set WORK.TEMP was not replaced because this step was stopped. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.01 seconds
When you said to assign values is such as initial values? Like L=0 .......
Could you help how to write this code?
If someone said to you: "I have a formula k=(Tc-To)/(To-Tb), can you tell me what is the value of k?", what would your first question be?
Thanks for the answer.
The "k" and "l" are just index to converge L and U in the iterative process. Such as the steps in image below:
Because the model sometimes provide exagered Tb(base or minimum) and Tc(ceiling or maximum) temperatures, and this iteration process try to solve this problem by calculting L and U for recalculted Tb and Tc.
In the process above To is optimum temperature.
@Thi_Oliveira wrote:
Thanks for the answer.
The "k" and "l" are just index to converge L and U in the iterative process. Such as the steps in image below:
Because the model sometimes provide exagered Tb(base or minimum) and Tc(ceiling or maximum) temperatures, and this iteration process try to solve this problem by calculting L and U for recalculted Tb and Tc.
In the process above To is optimum temperature.
I don't think this answers my question, which was: If someone said to you: "I have a formula k=(Tc-To)/(To-Tb), can you tell me what is the value of k?", what would your first question be?
The "k" represents the range of temperatures where there are plant growth in the study.
Well, ok, this isn't working.
You cannot calculate K if you don't have values for To, Tc and Tb. Correct?
So, you have to tell SAS what the values of To, Tc and Tb are, or nothing gets calculated.
I inform the values of To, Tb and Tc.
data temp; To=14; Tb=4; Tc=20; k=(Tc-To)/(To-Tb); l=(0.05**2)*(To-Tb)*((Tc-To)**k); do i=1 to 50 by 1; i+1= l/(((Tc-Tb)**(k+1))*((1-i)**k)); output; end; run;
However the log indicates an error:
416 data temp; 417 To=14; 418 Tb=4; 419 Tc=20; 420 k=(Tc-To)/(To-Tb); 421 l=(0.05**2)*(To-Tb)*((Tc-To)**k); 422 do i=1 to 50 by 1; 423 i+1= l/(((Tc-Tb)**(k+1))*((1-i)**k)); 424 output; 425 end; 426 run; NOTE: Division by zero detected at line 423 column 7. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. NOTE: Invalid argument(s) to the exponential operator "**" at line 423 column 32. To=14 Tb=4 Tc=20 k=0.6 l=0.0732539013 i=51 _ERROR_=1 _N_=1 NOTE: Missing values were generated as a result of performing an operation on missing values. Each place is given by: (Number of times) at (Line):(Column). 49 at 423:25 NOTE: Mathematical operations could not be performed at the following places. The results of the operations have been set to missing values. Each place is given by: (Number of times) at (Line):(Column). 1 at 423:7 49 at 423:32 NOTE: The data set WORK.TEMP has 50 observations and 6 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds
Now, I don't know what is going on. In the article, the authors have said to start with L=0 and then proceed to the interaction until convergence is achieved. However, I still thinking that I'm not writting on right way.
data temp;
To=14;
Tb=4;
Tc=20;
k=(Tc-To)/(To-Tb);
array LL l1-l50;
ll(1)=(0.05**2)*(To-Tb)*((Tc-To)**k);
do i=1 to 49 by 1;
LL(i+1)= LL(1)/(((Tc-Tb)**(k+1))*((1-LL(i))**k));
output;
end;
run;
Does this do what you want? You know the forumlas, I don't.
Thanks for the answer PaigeMiler. But, it isn't. I will share again the Appendix in the article.
I only have the values of To, Tb and Tc, all the other must be estimated.
Maybe I have to do a DO until code becasue I have to achieved the convergence, because in the end I only have one value of L and U (convergence), and this value I will sum in Tb (minimum temperature) and Tc (maximum temperature) to corret it.
I read a lot this example in the article but it is very confuse to understand this iterative procedure.
If we could continue to talk about this, I I appreciate it.
Pick a simpler formula, provide values for the variables like Tc Tb To and show us what you expect to get for output from that data step for like 3 observations.
I suspect that you want to retain L and U and OUTPUT new versions in the loop instead of attempting to create 11 variables whose names start with L and U
This may give you an idea of how to create multiple records.
data junk; Retain l 5; do i=0 to 5; output; /*being at the start of the loop the value of L going in is output*/ l= l*5; end; run;
The [ ] in a data step are used only for array references.
Thanks for the answer.
The "k" and "l" are just index to converge L and U in the iterative process. Such as the steps in image below:
Because the model sometimes provide exagered Tb(base or minimum) and Tc(ceiling or maximum) temperatures, and this iteration process try to solve this problem by calculting L and U for recalculted Tb and Tc.
In the process above To is optimum temperature.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.