BookmarkSubscribeRSS Feed
annie_1
Fluorite | Level 6

Hi, 

I have a days worth of data that is time marked almost every second, where every second a concentration of X chemical is recorded.

I have been able to round the time to the nearest minute in SAS, however I am trying to get the average of all the concentrations starting with my first recorded minutes until the 5th minute, and then so on every 5 minutes.

So in this case I want the average of '4:42, 4:43, 4:44, 4:45, and 4:46' then the next five minutes etc.

Below is a snippet of the data. The first two columns are the original date and time, X is the chemical and its recorded volume. Date time is just the combination of the first two columns, and the second to last column is the SAS_rounded time, and the last column is the Date and Sas_rounded time added together.

As you can see I have multiple values for just one minute. 

I tried using the MOVAVE function with a unit of 5, but it was only taking the average of the first five entries of X, and so on. I want the code to be able to get the average of the first 5 minutes of X recordings and so on.

I also added the code I tried to use for this.

Any help with this would be great, thanks.

 

Example of Data

DATETIMEXDate timesas_roundedsas_datetime
5/26/20194:42:04.10035/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:04.0255/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:05.36235/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:061.52565/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:0722.36265/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:072.22565/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:083.34585/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:096.35655/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:107.56425/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:108.23565/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:112.56555/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:125.2355/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:13-8.225/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:13-.1235/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:14-5.2355/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:155.25465/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:16-20.2565/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:166.34125/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:17-5.25325/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:183.56875/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:196.435/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:195.23565/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:200.25355/26/2019 4:424:42:00 AM5/26/2019 4:42
5/26/20194:42:21-2.52545/26/2019 4:424:42:00 AM5/26/2019 4:42

 

proc expand data = twentysix out = twentysix_5min method=None;
CONVERT X = X_ave/TRANSFORM=(MOVAVE 5);
by sas_datetime;
run;
proc expand data = twentysix out = twentysix_5min_TRY method=None;
CONVERT X = X_ave / TRANSOUT=(MOVAVE 5 trim 4);
by sas_datetime;
run;

5 REPLIES 5
Reeza
Super User
You definitely don't want that BY statement in there.

Try it without and then with MOVAVE but SAS marks time in seconds, so 5 minutes may be 60*5 = 300?

If not, its pretty straightforward to do via PROC MEANS or other options. Are you trying to do a moving average or an average for every 5 minute? I thought you want the average for 0-4, 5-9 not 0-4, 1-5, 2-6, which is the moving average.
annie_1
Fluorite | Level 6

You are correct I want the average for 0-4 min, 5-9 min etc.

           So I should take out the transform function and use the proc means option?

 

Thank you for responding.

 

Reeza
Super User
You need proc means but unfortunately you'll have to either create a custom format to group your times or create a new variable that will group them into 5 minutes. Do you know how to do that or do you need help with it? If you're a beginner, creating a new variable that had the grouping is the best method. I would not use IF/THEN statements but use the fact that times are in seconds and that you can round them to the nearest value. You usually have to adjust the formula slightly, by subtracting or adding a constant to get exactly what you want for rounding.
Reeza
Super User
data want;
set have;

*find start of time block;
time_start = max(round(time - 150 , 300), 0);
*find end of time block;
time_end = round(time + 150, 300);
*create a text label of data;
time_group = catx(" to ", put(minute(time_start), z2.), put(minute(time_end), z2.));
*format to control appearance;
format time: time.;
run;

May need some tweaks, not fully tested.

annie_1
Fluorite | Level 6

OK, great. I will try it out.

Thank you for the code, I appreciate your help.

 

 

A

 

 

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 5 replies
  • 857 views
  • 1 like
  • 2 in conversation