Divide timeseries to monthly ones

For a specific year I have created an hourly timetable using retime.
How can I divide into monthly ?

 Accepted Answer

A for loop is the easiest way to do this —
LD = load(websave('dataset','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1255052/dataset.mat'));
T = LD.TT1;
VarPerHour = retime(T, 'hourly', 'sum')
VarPerHour = 8760×1 timetable
date_time Temperature __________________ ___________ 01-Jan-19 00:00:00 588 01-Jan-19 01:00:00 608.11 01-Jan-19 02:00:00 608.25 01-Jan-19 03:00:00 608.33 01-Jan-19 04:00:00 608.25 01-Jan-19 05:00:00 608.4 01-Jan-19 06:00:00 608.59 01-Jan-19 07:00:00 608.9 01-Jan-19 08:00:00 609.32 01-Jan-19 09:00:00 599.51 01-Jan-19 10:00:00 609.61 01-Jan-19 11:00:00 609.51 01-Jan-19 12:00:00 609.39 01-Jan-19 13:00:00 609.44 01-Jan-19 14:00:00 609.58 01-Jan-19 15:00:00 609.83
for k = 1:12
MMidx = month(VarPerHour.date_time) == k;
VarPerHourMonth{k,:} = VarPerHour(MMidx,:);
end
VarPerHourMonth
VarPerHourMonth = 12×1 cell array
{744×1 timetable} {672×1 timetable} {744×1 timetable} {720×1 timetable} {744×1 timetable} {720×1 timetable} {744×1 timetable} {744×1 timetable} {720×1 timetable} {744×1 timetable} {720×1 timetable} {744×1 timetable}
VarPerHourMonth{1}(1:5,:)
ans = 5×1 timetable
date_time Temperature __________________ ___________ 01-Jan-19 00:00:00 588 01-Jan-19 01:00:00 608.11 01-Jan-19 02:00:00 608.25 01-Jan-19 03:00:00 608.33 01-Jan-19 04:00:00 608.25
VarPerHourMonth{12}(1:5,:)
ans = 5×1 timetable
date_time Temperature __________________ ___________ 01-Dec-19 00:00:00 590.64 01-Dec-19 01:00:00 193.5 01-Dec-19 02:00:00 0 01-Dec-19 03:00:00 0 01-Dec-19 04:00:00 0
This uses an existing timetable. It should work with the one you are currently using as well.
.

10 Comments

This was an adventure!
This looks a bit more complicated than it actually is.
I can’t get them exactly in the format you want, however this is reasonably close.
In any event, it’s the best I can do —
LD = load(websave('dataset','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1255052/dataset.mat'));
T = LD.TT1;
VarPerHour = retime(T, 'hourly', 'sum')
VarPerHour = 8760×1 timetable
date_time Temperature __________________ ___________ 01-Jan-19 00:00:00 588 01-Jan-19 01:00:00 608.11 01-Jan-19 02:00:00 608.25 01-Jan-19 03:00:00 608.33 01-Jan-19 04:00:00 608.25 01-Jan-19 05:00:00 608.4 01-Jan-19 06:00:00 608.59 01-Jan-19 07:00:00 608.9 01-Jan-19 08:00:00 609.32 01-Jan-19 09:00:00 599.51 01-Jan-19 10:00:00 609.61 01-Jan-19 11:00:00 609.51 01-Jan-19 12:00:00 609.39 01-Jan-19 13:00:00 609.44 01-Jan-19 14:00:00 609.58 01-Jan-19 15:00:00 609.83
for k = 1:12
MMidx = month(VarPerHour.date_time) == k;
VarPerHourMonth{k,:} = VarPerHour(MMidx,:);
end
for k = 1:12
TTTemp = VarPerHourMonth{k}; % Create Temporary 'timetable'
Hours = hour(TTTemp.date_time); % Create 'Hours' Variable
[y,m,d] = ymd(TTTemp.date_time); % Begin To Create 'Date' Variable
Date = datetime(y,m,d); % Finish Creating 'Date' Variable
TTTemp = addvars(TTTemp, Date, Hours,'Before','Temperature'); % Add 'Hours' & 'Date' Variables
TTTemp.Properties.VariableNames(1:2) = {'Date','Hours'}; % Name 'Hours' & 'Date' Variables
TTTempT = timetable2table(TTTemp); % Convert To 'table'
VarPerHourMonthT{k,:} = unstack(TTTempT(:,2:end),'Temperature','Hours', 'VariableNamingRule','preserve'); % Unstack & Write To Cell Array
end
VarPerHourMonthT % Display Results
VarPerHourMonthT = 12×1 cell array
{31×25 table} {28×25 table} {31×25 table} {30×25 table} {31×25 table} {30×25 table} {31×25 table} {31×25 table} {30×25 table} {31×25 table} {30×25 table} {31×25 table}
VarPerHourMonthT{1}(1:5,:)
ans = 5×25 table
Date 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ___________ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ 01-Jan-2019 588 608.11 608.25 608.33 608.25 608.4 608.59 608.9 609.32 599.51 609.61 609.51 609.39 609.44 609.58 609.83 609.97 610.21 610.35 610.42 610.52 610.54 610.72 610.54 02-Jan-2019 589.97 610.02 609.79 609.47 609.06 608.76 608.66 608.54 608.66 608.75 608.57 608.08 607.77 607.33 606.85 606.66 606.4 606.22 606.29 606.31 606.17 605.95 605.57 514.48 03-Jan-2019 574.56 604.75 604.71 604.53 604.05 603.61 603.22 603.14 603.77 604.38 604.76 604.79 604.45 604.75 604.73 604.92 605.31 605.53 606.32 606.63 607.06 607.59 607.94 608.23 04-Jan-2019 588.18 608.74 608.99 609.25 609.32 609.3 609.35 609.49 609.92 610.62 610.78 610.59 610.29 610.01 609.96 609.88 609.79 610.11 610.26 610.51 610.71 610.28 610.17 610.06 05-Jan-2019 589.38 609.63 609.23 609.37 609.24 608.86 608.74 608.44 608.65 609.31 609.42 609.41 608.9 608.53 608.53 608.6 608.7 608.82 609.15 609.34 609.36 609.36 609.39 609.23
VarPerHourMonthT{12}(1:5,:)
ans = 5×25 table
Date 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ___________ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ 01-Dec-2019 590.64 193.5 0 0 0 0 0 0 0 0 0 603.21 613.27 613.16 613.12 613.12 613.17 163.52 0 0 0 0 0 0 02-Dec-2019 583.83 614.47 614.55 614.53 614.32 614.18 614.23 614.26 614.48 614.56 614.6 614.43 614.13 613.97 613.75 613.47 613.22 613.05 612.97 613.07 613.12 613.15 613.04 613.09 03-Dec-2019 592.37 612.51 612.56 612.35 611.93 611.72 611.59 611.5 611.43 611.41 611.53 611.47 611.56 611.59 611.35 611.2 611.2 611.22 611.07 611.13 611.06 611.07 611.08 610.76 04-Dec-2019 589.94 610.24 610.45 610.26 609.94 609.84 609.82 610.14 610.25 610.56 611.45 600.92 610.75 610.62 610.46 590.17 152.67 0 0 0 0 0 0 0 05-Dec-2019 583.18 613.92 614.01 614.16 614.15 614.12 614.21 614.31 614.68 604.68 614.93 614.73 614.95 614.92 614.91 614.97 614.94 615.21 615.25 615.63 615.94 616 616.06 616.11
The new ‘VarPerHourMonthT’ cell array is of table arrays, not timetable arrays because I doubt that timetable arrays would support this format. The essential function here is the unstack function, and most of the code in the loop iterations is devoted to creating table arrays that are compatible with it. Using unstack on the timetable arrays themselves is possible (I did that first), however they do not produce the result you want, so I adopted this approach instead. (The problem with using unstack on the timetable arrays themselves is that it produces a diagonal matrix of ‘Temperature’ sums in a matrix of NaN values for each hour, rather than a single row. To get the result you want required creating both the ‘Date’ and ‘Hour’ variables, converting the timetable arrays to table arrays, eliminating the ‘date_time’ variable, and then using unstack on the table arrays.)
I did my best to comment-document my code here, along with describing it.
.
Thank you for the detailed approach. Using your dataset I receive the following error:
Error using tabular/unstack (line 112)
Invalid parameter name: VariableNamingRule.
My pleasure!
My code works in R2022b. Since you apparently have a different (earlier) version/release (that I may not have access to even if I knew what it was), you may have to experiment with my code to get the same result. For the time being, eliminate that part of my unstack call and hope for the best! (It may be necessary to use the ‘VarPerHourMonthT{k,:}.Properties.VariableNames’ or ‘VarPerHourMonthT.Properties.VariableNames’ option to set their names. I am hesitant to experiment with that with my code since it works as written.)
Upgrading to R2022b would be the easiest option if that is available to you.
As always, my pleasure!
Yes.
See the documentation section on Spreadsheet Files Only . It will probably be necesary to use a for loop to write to each sheet. (I have never had to do this, so I have no experience with it.)
Testing it here —
LD = load(websave('dataset','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1255052/dataset.mat'));
T = LD.TT1;
VarPerHour = retime(T, 'hourly', 'sum')
VarPerHour = 8760×1 timetable
date_time Temperature __________________ ___________ 01-Jan-19 00:00:00 588 01-Jan-19 01:00:00 608.11 01-Jan-19 02:00:00 608.25 01-Jan-19 03:00:00 608.33 01-Jan-19 04:00:00 608.25 01-Jan-19 05:00:00 608.4 01-Jan-19 06:00:00 608.59 01-Jan-19 07:00:00 608.9 01-Jan-19 08:00:00 609.32 01-Jan-19 09:00:00 599.51 01-Jan-19 10:00:00 609.61 01-Jan-19 11:00:00 609.51 01-Jan-19 12:00:00 609.39 01-Jan-19 13:00:00 609.44 01-Jan-19 14:00:00 609.58 01-Jan-19 15:00:00 609.83
for k = 1:12
MMidx = month(VarPerHour.date_time) == k;
VarPerHourMonth{k,:} = VarPerHour(MMidx,:);
end
for k = 1:12
TTTemp = VarPerHourMonth{k}; % Create Temporary 'timetable'
Hours = hour(TTTemp.date_time); % Create 'Hours' Variable
[y,m,d] = ymd(TTTemp.date_time); % Begin To Create 'Date' Variable
Date = datetime(y,m,d); % Finish Creating 'Date' Variable
TTTemp = addvars(TTTemp, Date, Hours,'Before','Temperature'); % Add 'Hours' & 'Date' Variables
TTTemp.Properties.VariableNames(1:2) = {'Date','Hours'}; % Name 'Hours' & 'Date' Variables
TTTempT = timetable2table(TTTemp); % Convert To 'table'
VarPerHourMonthT{k,:} = unstack(TTTempT(:,2:end),'Temperature','Hours', 'VariableNamingRule','preserve'); % Unstack & Write To Cell Array
end
Filename = 'RainPerHourMonth.xlsx';
for k = 1:12
writetable(VarPerHourMonthT{k}, Filename, 'Sheet',k)
end
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
Warning: Added specified worksheet.
T6 = readtable(Filename, 'Sheet',6, 'VariableNamingRule','preserve') % Check 6
T6 = 30×25 table
Date 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ___________ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ 01-Jun-2019 590.12 610.21 609.91 609.69 609.39 609.26 609.45 609.56 609.62 609.79 609.73 609.8 609.85 609.93 609.99 610.05 609.95 609.9 609.82 609.79 609.87 610.11 610.22 610.32 02-Jun-2019 589.91 610 609.75 609.56 609.36 609.43 609.4 609.48 609.66 609.82 609.93 610.05 610.08 610.03 609.77 609.73 609.75 609.61 609.64 609.86 610.03 610.06 610.54 559.69 03-Jun-2019 590.07 610.38 610.19 609.93 609.65 609.56 609.55 609.72 610.1 610.23 610.29 610.35 610.37 610.34 610.3 610.31 610.13 610.13 609.77 609.69 609.61 609.7 609.99 610.16 04-Jun-2019 589.7 609.81 609.39 609.14 608.96 608.84 608.93 608.96 609.02 609.24 609.31 609.47 609.6 609.56 609.54 609.37 609.11 608.87 608.7 608.59 608.64 608.66 608.87 608.92 05-Jun-2019 588.63 608.9 608.82 608.6 608.47 608.43 608.46 608.49 608.58 608.8 608.85 608.95 609.06 608.94 608.78 608.62 608.55 608.46 608.38 608.45 608.63 608.85 609.36 609.43 06-Jun-2019 589.19 609.53 609.6 609.66 609.68 609.82 609.87 610.12 610.34 610.58 610.71 610.7 610.89 610.93 610.89 610.83 610.69 610.58 610.6 610.62 610.87 610.99 611.3 611.32 07-Jun-2019 591.04 611.48 611.42 611.23 611.21 611.2 611.38 611.55 611.61 611.72 611.79 611.83 611.97 611.91 611.84 611.74 611.61 611.56 611.45 611.39 611.56 611.71 612.04 612.22 08-Jun-2019 591.75 612.06 611.75 611.64 611.57 611.44 611.45 611.56 611.67 611.79 611.78 611.53 611.46 611.41 611.2 610.94 610.69 610.4 610.22 610.18 610.24 610.43 610.6 610.84 09-Jun-2019 590.49 610.77 610.68 610.37 610.12 609.74 609.8 609.97 610.16 610.2 609.81 609.51 609.18 172.6 0 0 0 0 0 0 0 0 0 0 10-Jun-2019 0 0 0 0 0 0 0 0 0 577.48 607.67 607.64 607.41 607.18 606.86 606.63 363.89 606.34 606.1 606.23 606.5 606.62 606.69 606.93 11-Jun-2019 586.4 606.44 606.44 606.31 606.12 605.98 606.08 606.26 606.4 606.48 606.49 606.62 606.75 606.81 606.55 606.3 606.37 606.63 607.04 607.08 607.06 607.5 607.95 607.93 12-Jun-2019 587.48 607.62 607.39 607.33 607.21 607.23 607.5 607.91 608.08 608.17 608.36 608.57 608.55 608.54 608.4 608.31 608.3 608.16 608.33 608.3 608.33 608.55 609.12 609.08 13-Jun-2019 588.75 609.03 608.79 608.66 608.59 608.66 608.89 609.09 609.46 609.72 609.8 609.93 609.9 609.72 609.48 609.34 609.24 609.14 609.03 608.98 609.02 609.13 609.46 609.63 14-Jun-2019 589.38 609.6 609.52 609.36 609.17 609.03 609.18 609.22 609.3 609.42 609.47 609.48 609.43 609.39 588.9 588.49 608.61 608.54 608.32 608.25 608.37 608.58 608.49 608.46 15-Jun-2019 588.22 608.57 608.22 607.96 607.86 607.64 607.61 607.68 607.83 607.89 607.87 607.7 607.65 607.37 607.15 606.85 606.86 606.62 606.46 606.43 606.35 606.53 606.74 607.02 16-Jun-2019 586.81 606.99 607.09 607.03 606.91 606.99 607.15 607.26 607.16 607.16 607.21 607.25 587.09 607.3 606.87 606.55 606.65 607.31 606.8 606.56 606.81 607.04 607.25 607.52
I do not understand the writetable warnings. It seems to work.
.
In your edit to your previous Comment, did anything change that requires a specific reply? (To the best of my knowledge, I do not have the table you are referring to, so I am using the one I have, and the code I created previously to work with it.)
No @Star Strider, I had a typo error and correct it!
Let’s do that experiment —
LD = load(websave('dataset','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1255052/dataset.mat'));
T = LD.TT1;
VarPerHour = retime(T, 'hourly', 'sum')
VarPerHour = 8760×1 timetable
date_time Temperature __________________ ___________ 01-Jan-19 00:00:00 588 01-Jan-19 01:00:00 608.11 01-Jan-19 02:00:00 608.25 01-Jan-19 03:00:00 608.33 01-Jan-19 04:00:00 608.25 01-Jan-19 05:00:00 608.4 01-Jan-19 06:00:00 608.59 01-Jan-19 07:00:00 608.9 01-Jan-19 08:00:00 609.32 01-Jan-19 09:00:00 599.51 01-Jan-19 10:00:00 609.61 01-Jan-19 11:00:00 609.51 01-Jan-19 12:00:00 609.39 01-Jan-19 13:00:00 609.44 01-Jan-19 14:00:00 609.58 01-Jan-19 15:00:00 609.83
for k = 1:12
MMidx = month(VarPerHour.date_time) == k;
VarPerHourMonth{k,:} = VarPerHour(MMidx,:);
end
for k = 1:12
TTTemp = VarPerHourMonth{k}; % Create Temporary 'timetable'
Hours = hour(TTTemp.date_time); % Create 'Hours' Variable
[y,m,d] = ymd(TTTemp.date_time); % Begin To Create 'Date' Variable
Date = datetime(y,m,d); % Finish Creating 'Date' Variable
TTTemp = addvars(TTTemp, Date, Hours,'Before','Temperature'); % Add 'Hours' & 'Date' Variables
TTTemp.Properties.VariableNames(1:2) = {'Date','Hours'}; % Name 'Hours' & 'Date' Variables
TTTempT = timetable2table(TTTemp); % Convert To 'table'
VarPerHourMonthT{k,:} = unstack(TTTempT(:,2:end),'Temperature','Hours', 'VariableNamingRule','preserve'); % Unstack & Write To Cell Array
MMM{k,:} = month(TTTemp.date_time(1,:),'shortname');
end
Filename = 'RainPerHourMonth.xlsx';
for k = 1:12
writetable(VarPerHourMonthT{k}, Filename, 'Sheet',string(MMM{k}))
end
T6 = readtable(Filename, 'Sheet','Jun', 'VariableNamingRule','preserve') % Check 6
T6 = 30×25 table
Date 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ___________ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ ______ 01-Jun-2019 590.12 610.21 609.91 609.69 609.39 609.26 609.45 609.56 609.62 609.79 609.73 609.8 609.85 609.93 609.99 610.05 609.95 609.9 609.82 609.79 609.87 610.11 610.22 610.32 02-Jun-2019 589.91 610 609.75 609.56 609.36 609.43 609.4 609.48 609.66 609.82 609.93 610.05 610.08 610.03 609.77 609.73 609.75 609.61 609.64 609.86 610.03 610.06 610.54 559.69 03-Jun-2019 590.07 610.38 610.19 609.93 609.65 609.56 609.55 609.72 610.1 610.23 610.29 610.35 610.37 610.34 610.3 610.31 610.13 610.13 609.77 609.69 609.61 609.7 609.99 610.16 04-Jun-2019 589.7 609.81 609.39 609.14 608.96 608.84 608.93 608.96 609.02 609.24 609.31 609.47 609.6 609.56 609.54 609.37 609.11 608.87 608.7 608.59 608.64 608.66 608.87 608.92 05-Jun-2019 588.63 608.9 608.82 608.6 608.47 608.43 608.46 608.49 608.58 608.8 608.85 608.95 609.06 608.94 608.78 608.62 608.55 608.46 608.38 608.45 608.63 608.85 609.36 609.43 06-Jun-2019 589.19 609.53 609.6 609.66 609.68 609.82 609.87 610.12 610.34 610.58 610.71 610.7 610.89 610.93 610.89 610.83 610.69 610.58 610.6 610.62 610.87 610.99 611.3 611.32 07-Jun-2019 591.04 611.48 611.42 611.23 611.21 611.2 611.38 611.55 611.61 611.72 611.79 611.83 611.97 611.91 611.84 611.74 611.61 611.56 611.45 611.39 611.56 611.71 612.04 612.22 08-Jun-2019 591.75 612.06 611.75 611.64 611.57 611.44 611.45 611.56 611.67 611.79 611.78 611.53 611.46 611.41 611.2 610.94 610.69 610.4 610.22 610.18 610.24 610.43 610.6 610.84 09-Jun-2019 590.49 610.77 610.68 610.37 610.12 609.74 609.8 609.97 610.16 610.2 609.81 609.51 609.18 172.6 0 0 0 0 0 0 0 0 0 0 10-Jun-2019 0 0 0 0 0 0 0 0 0 577.48 607.67 607.64 607.41 607.18 606.86 606.63 363.89 606.34 606.1 606.23 606.5 606.62 606.69 606.93 11-Jun-2019 586.4 606.44 606.44 606.31 606.12 605.98 606.08 606.26 606.4 606.48 606.49 606.62 606.75 606.81 606.55 606.3 606.37 606.63 607.04 607.08 607.06 607.5 607.95 607.93 12-Jun-2019 587.48 607.62 607.39 607.33 607.21 607.23 607.5 607.91 608.08 608.17 608.36 608.57 608.55 608.54 608.4 608.31 608.3 608.16 608.33 608.3 608.33 608.55 609.12 609.08 13-Jun-2019 588.75 609.03 608.79 608.66 608.59 608.66 608.89 609.09 609.46 609.72 609.8 609.93 609.9 609.72 609.48 609.34 609.24 609.14 609.03 608.98 609.02 609.13 609.46 609.63 14-Jun-2019 589.38 609.6 609.52 609.36 609.17 609.03 609.18 609.22 609.3 609.42 609.47 609.48 609.43 609.39 588.9 588.49 608.61 608.54 608.32 608.25 608.37 608.58 608.49 608.46 15-Jun-2019 588.22 608.57 608.22 607.96 607.86 607.64 607.61 607.68 607.83 607.89 607.87 607.7 607.65 607.37 607.15 606.85 606.86 606.62 606.46 606.43 606.35 606.53 606.74 607.02 16-Jun-2019 586.81 606.99 607.09 607.03 606.91 606.99 607.15 607.26 607.16 607.16 607.21 607.25 587.09 607.3 606.87 606.55 606.65 607.31 606.8 606.56 606.81 607.04 607.25 607.52
For some reason, writetable doesn’t like the cell array (even though indexing into it should produce a character array), however it accepts the string argument. Referring to it by name in the readtable test works. (The ‘MMM’ cell array didn’t initially appear in this version of my code, so I added it in the loop.)
So, an emphatic ‘Yes!’
.
As always, my pleasure!

Sign in to comment.

More Answers (1)

Hi Ancalogon,
Having a look at the documentation here; you can just replace hourly with any timestep such as:
Time Step
'yearly'
'quarterly'
'monthly'
'weekly'
'daily'
'hourly'
'minutely'
'secondly'
Have you tried;
VarPermonth = retime(T, 'monthly', 'sum');
Let me know if this is what you are looking for, if not please provide a snippit of the data and the expected output.
Christopher

1 Comment

Hi Ancalagon,
I get what you want now.
What you really need to do is filter ValPerHour by months, heres an example of how to do so:
And also an ealier suggestion from Walter;
I hope this helps!
Christopher

Sign in to comment.

Categories

Tags

Asked:

on 15 Jan 2023

Edited:

on 6 Jan 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!