Hello,
I'm doing some data manipulation in SAS 9.4 before further analysis. I have several years of temperature data and want to do further calculations if there has been no killing frost in the fall yet. I wrote the following statements to make frost =1 on days where the temperature was less than 2 degrees.
if temp<-2 and day>180 then frost=1;
else frost=0;
Is there a way to make frost =1 for the rest of the days following the first frost in that year, and then reset for the next year?
I was exploring do loops but I'm not sure if that would fit what I'm looking for or not.
Thanks for your help.
data want;
set have;
by year;
retain frost;
if first.year then frost = 0;
if day > 180 and temp <= 2 then frost = 1;
run;
Maybe this:
if temp<-2 and day>180 and frost=0 then frost+1;
By the way, it helps if you show a portion of the data. This code fragment and @Reeza 's suggestion work if there is one observation for each day (and so DO loops are not useful here), but it does not work for other layouts of the data (and maybe do loops work there); and we really shouldn't have to guess what your data looks like.
RETAIN and BY group processing. Please supply example data (as advised when you posted).
data want;
set have;
by year;
retain frost;
if first.year then frost = 0;
if day > 180 and temp <= 2 then frost = 1;
run;
This code works for me! Thanks for your help!
A little complicated solution (than what has already been suggested) but this is "somewhat" an alternative solution. The data you have shared is for one year only and for first 100 days. So not sure this will work out. Please let me know the outcome. I am curious how was the output of this code.
Thank you.
DATA Temp_Processed;
SET Temp; /*Change the name for your dataset name*/
RETAIN Year_Flag 0;
RETAIN Frost 0;
IF Year_Flag ^= 0 THEN OUTPUT;
ELSE IF DAY > 180 and Temp < 2 and Year_Flag=0 THEN DO; Frost = 1; Year_Flag=Year; OUTPUT; END;
ELSE IF DAY <= 180 THEN DO; Frost = 0; Year_Flag=0; OUTPUT; END;
RUN;
I know why because I kept the first condition as not correct. I have changed it. I was tired last night and could not spot it (neither the error nor the fact that the excel file you sent had approximately 1460 rows. SAS Studio just outputs 100 rows at a time, by default. So I am sorry about all that. Here is the code.
DATA Temp_Processed;
SET Temp;/*Change as per your data name*/
RETAIN Year_Flag 0;
RETAIN Frost 0;
IF Year_Flag ^=0 and DAY > 180 and Temp < 2 THEN
OUTPUT;
ELSE IF DAY > 180 and Temp < 2 and Year_Flag=0 THEN
DO;
Frost=1;
Year_Flag=Year;
OUTPUT;
END;
ELSE IF DAY <=180 THEN
DO;
Frost=0;
Year_Flag=0;
OUTPUT;
END;
RUN;
You can confirm that for the intended Frost range, it is correctly assigned ... by doing a simple PROC SQL.
PROC SQL;
SELECT
MIN(DAY) AS StartingDate,
MAX(DAY) AS EndDate,
Year_Flag,
Frost
FROM
Temp_Processed
GROUP BY
Year_Flag,
Frost;
QUIT;
It outputs the intended result.
Sorry again for creating a confusion. Fortunately you got a solution that was working for you and thus your time was not lost by my solution.
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.